/de.monochromata.eclipse.anaphors.test/src/test/java/de/monochromata/eclipse/persp/PerspectivationPositionTest.java

https://gitlab.com/monochromata-de/de.monochromata.eclipse.anaphors · Java · 859 lines · 613 code · 207 blank · 39 comment · 0 complexity · 8f781a8a022afd41f6220a0be13224bd MD5 · raw file

  1. package de.monochromata.eclipse.persp;
  2. import static de.monochromata.eclipse.persp.HidePosition.HIDE_CATEGORY;
  3. import static de.monochromata.eclipse.persp.PerspectivationPosition.PERSPECTIVATION_CATEGORY;
  4. import static de.monochromata.eclipse.persp.ToLowerCasePosition.TO_LOWER_CASE_CATEGORY;
  5. import static de.monochromata.eclipse.position.DoublyLinkedPosition.link;
  6. import static java.util.Arrays.asList;
  7. import static java.util.Collections.emptyList;
  8. import static org.assertj.core.api.Assertions.assertThat;
  9. import java.lang.reflect.Field;
  10. import java.util.ArrayList;
  11. import java.util.concurrent.atomic.AtomicBoolean;
  12. import java.util.concurrent.atomic.AtomicInteger;
  13. import java.util.function.Consumer;
  14. import org.eclipse.jface.text.BadLocationException;
  15. import org.eclipse.jface.text.Document;
  16. import org.eclipse.jface.text.DocumentEvent;
  17. import org.eclipse.jface.text.IDocument;
  18. import org.junit.Test;
  19. import de.monochromata.anaphors.perspectivation.Perspectivation;
  20. import de.monochromata.eclipse.anaphors.position.PositionsTesting;
  21. public class PerspectivationPositionTest implements PositionsTesting {
  22. private final IDocument originDocument = new Document();
  23. private final PerspectivationDocumentManager manager = new PerspectivationDocumentManager();
  24. private final PerspectivationDocument document = manager.createSlaveDocument(originDocument);
  25. @Test
  26. public void isEnabledByDefault() {
  27. assertThat(new PerspectivationPosition(0, 10).isEnabled()).isTrue();
  28. }
  29. @Test
  30. public void setEnabledTogglesIsEnabled() throws BadLocationException {
  31. final PerspectivationPosition position = new PerspectivationPosition(0, 1);
  32. assertThat(position.isEnabled()).isTrue();
  33. position.setEnabled(false, document);
  34. assertThat(position.isEnabled()).isFalse();
  35. }
  36. @Test
  37. public void setEnabledPerformsPerspectivation() throws Exception {
  38. final String initialText = "The Quick Brown Fox Is Slow Today.";
  39. document.set(initialText);
  40. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  41. asList(new Perspectivation.ToLowerCase(6), new Perspectivation.Hide(0, 6)));
  42. position.notify(new DocumentEvent(), document);
  43. position.undoPerspectivation();
  44. assertThat(document.get()).isEqualTo("The Quick Brown Fox Is Slow Today.");
  45. final Field isEnabledField = PerspectivationPosition.class.getDeclaredField("isEnabled");
  46. isEnabledField.setAccessible(true);
  47. isEnabledField.set(position, false);
  48. position.setEnabled(true, document);
  49. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  50. }
  51. @Test
  52. public void setEnabledDoesNotPerformPerspectivationTwice() throws Exception {
  53. final String initialText = "The Quick Brown Fox Is Slow Today.";
  54. document.set(initialText);
  55. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  56. asList(new Perspectivation.ToLowerCase(6), new Perspectivation.Hide(0, 6)));
  57. position.notify(new DocumentEvent(), document);
  58. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  59. position.setEnabled(true, document);
  60. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  61. }
  62. @Test
  63. public void setEnabledUndoesPerspectivation() throws BadLocationException {
  64. final String initialText = "The Quick Brown Fox Is Slow Today.";
  65. document.set(initialText);
  66. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  67. asList(new Perspectivation.ToLowerCase(6), new Perspectivation.Hide(0, 6)));
  68. position.notify(new DocumentEvent(), document);
  69. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  70. position.setEnabled(false, document);
  71. assertThat(position.isEnabled()).isFalse();
  72. assertThat(document.get()).isEqualTo("The Quick Brown Fox Is Slow Today.");
  73. }
  74. @Test
  75. public void setEnabledDoesNotUndoPerspectivationTwice() throws BadLocationException {
  76. final String initialText = "The Quick Brown Fox Is Slow Today.";
  77. document.set(initialText);
  78. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  79. asList(new Perspectivation.ToLowerCase(6), new Perspectivation.Hide(0, 6)));
  80. position.notify(new DocumentEvent(), document);
  81. position.undoPerspectivation();
  82. assertThat(document.get()).isEqualTo("The Quick Brown Fox Is Slow Today.");
  83. assertThat(position.isEnabled()).isTrue();
  84. position.setEnabled(false, document);
  85. assertThat(position.isEnabled()).isFalse();
  86. assertThat(document.get()).isEqualTo("The Quick Brown Fox Is Slow Today.");
  87. }
  88. @Test
  89. public void conditionHasBeenMetReturnsFalseInitially() {
  90. assertThat(new PerspectivationPosition(0, 1).conditionHasBeenMet()).isFalse();
  91. }
  92. @Test
  93. public void conditionHasBeenMetReturnsTrueAfterNotificationOfDisabledPosition() throws BadLocationException {
  94. final PerspectivationPosition position = new PerspectivationPosition(event -> true, emptyList());
  95. position.setEnabled(false, document);
  96. position.notify(new DocumentEvent(), document);
  97. assertThat(position.conditionHasBeenMet()).isTrue();
  98. }
  99. @Test
  100. public void conditionHasBeenMetReturnsTrueAfterSuccessfulPerspectivation() throws BadLocationException {
  101. final PerspectivationPosition position = new PerspectivationPosition(unused -> true, emptyList());
  102. position.notify(new DocumentEvent(), document);
  103. assertThat(position.conditionHasBeenMet()).isTrue();
  104. }
  105. @Test
  106. public void isPerspectivisedReturnsTrueAfterFulfilledPerspectivationPredicate() throws Exception {
  107. final PerspectivationPosition position = new PerspectivationPosition(unused -> true, emptyList());
  108. assertThat(position.isPerspectivated()).isFalse();
  109. position.notify(new DocumentEvent(), document);
  110. assertThat(position.isPerspectivated()).isTrue();
  111. }
  112. @Test
  113. public void isPerspectivisedReturnsFalseAfterNonMatchingPerspectivationPredicate() throws Exception {
  114. final PerspectivationPosition position = new PerspectivationPosition(unused -> false, emptyList());
  115. assertThat(position.isPerspectivated()).isFalse();
  116. position.notify(new DocumentEvent(), document);
  117. assertThat(position.isPerspectivated()).isFalse();
  118. }
  119. @Test
  120. public void perspectivationIsPerformedIfConditionIsFulfilled() throws Exception {
  121. final AtomicBoolean performed = new AtomicBoolean(false);
  122. final PerspectivationPosition position = new PerspectivationPosition(unused -> true,
  123. new ListForTestingForEach<>(() -> performed.set(true)));
  124. position.notify(new DocumentEvent(), document);
  125. assertThat(performed.get()).isTrue();
  126. }
  127. @Test
  128. public void perspectivationIsNotPerformedIfConditionIsNotFulfilled() throws Exception {
  129. final AtomicBoolean performed = new AtomicBoolean(false);
  130. final PerspectivationPosition position = new PerspectivationPosition(unused -> false,
  131. new ListForTestingForEach<>(() -> performed.set(true)));
  132. position.notify(new DocumentEvent(), document);
  133. assertThat(performed.get()).isFalse();
  134. }
  135. @Test
  136. public void perspectivationIsNotPerformedIfPositionIsDisabled() throws Exception {
  137. final AtomicBoolean performed = new AtomicBoolean(false);
  138. final PerspectivationPosition position = new PerspectivationPosition(unused -> true,
  139. new ListForTestingForEach<>(() -> performed.set(true)));
  140. position.setEnabled(false, document);
  141. position.notify(new DocumentEvent(), document);
  142. assertThat(performed.get()).isFalse();
  143. }
  144. @Test
  145. public void conditionalPerspectivationIsNotCheckedOncePerspectivationHasBeenPerformed() throws Exception {
  146. final AtomicInteger perspectivationCount = new AtomicInteger(0);
  147. final PerspectivationPosition position = new PerspectivationPosition(unused -> true,
  148. new ListForTestingForEach<>(() -> perspectivationCount.incrementAndGet()));
  149. position.notify(new DocumentEvent(), document);
  150. assertThat(perspectivationCount.get()).isEqualTo(1);
  151. position.notify(new DocumentEvent(), document);
  152. assertThat(perspectivationCount.get()).isEqualTo(1);
  153. }
  154. @Test
  155. public void perspectivationPerformsToLowerCase() throws Exception {
  156. final String initialText = "The Quick Brown Fox Is Slow Today.";
  157. document.set(initialText);
  158. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  159. asList(new Perspectivation.ToLowerCase(6)));
  160. position.notify(new DocumentEvent(), document);
  161. assertThat(document.get()).isEqualTo("The Quick brown Fox Is Slow Today.");
  162. }
  163. @Test
  164. public void perspectivationSavesToLowerCasePositionInPerspectivationPosition() throws Exception {
  165. document.set("The Quick Brown Fox Is Slow Today.");
  166. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  167. asList(new Perspectivation.ToLowerCase(6)));
  168. position.notify(new DocumentEvent(), document);
  169. assertThat(position.getToLowerCasePositions()).containsExactly(new ToLowerCasePosition(10));
  170. }
  171. @Test
  172. public void perspectivationPerformsHide() throws Exception {
  173. final String initialText = "The Quick Brown Fox Is Slow Today.";
  174. document.set(initialText);
  175. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  176. asList(new Perspectivation.Hide(0, 6)));
  177. position.notify(new DocumentEvent(), document);
  178. assertThat(document.get()).isEqualTo("The Brown Fox Is Slow Today.");
  179. }
  180. @Test
  181. public void perspectivationSavesHidePositionInPerspectivationPosition() throws Exception {
  182. document.set("The Quick Brown Fox Is Slow Today.");
  183. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  184. asList(new Perspectivation.Hide(0, 6)));
  185. position.notify(new DocumentEvent(), document);
  186. assertThat(position.getHidePositions()).containsExactly(new HidePosition(4, 6));
  187. }
  188. @Test
  189. public void perspectivationPerformsToLowerCaseAndHide() throws Exception {
  190. final String initialText = "The Quick Brown Fox Is Slow Today.";
  191. document.set(initialText);
  192. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  193. asList(new Perspectivation.ToLowerCase(6), new Perspectivation.Hide(0, 6)));
  194. position.notify(new DocumentEvent(), document);
  195. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  196. }
  197. @Test
  198. public void perspectivationPerformsHideAndToLowerCase() throws Exception {
  199. final String initialText = "The Quick Brown Fox Is Slow Today.";
  200. document.set(initialText);
  201. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  202. asList(new Perspectivation.Hide(0, 6), new Perspectivation.ToLowerCase(6)));
  203. position.notify(new DocumentEvent(), document);
  204. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  205. }
  206. @Test
  207. public void undoDoesNothingIfNotYetPerspectivated() throws Exception {
  208. final PerspectivationPosition position = new PerspectivationPosition(null, null);
  209. // Should not throw a NullPointerException since no action should be
  210. // taken.
  211. position.undoPerspectivation();
  212. }
  213. /**
  214. * This case is assumed due to a delay execution of setEnabled(false) that
  215. * already modified this.isEnabled, but not yet isPerspectivated.
  216. */
  217. @Test
  218. public void undoDoesNothingIfDisabledAfterPerspectivation() throws Exception {
  219. final String initialText = "The Quick Brown Fox Is Slow Today.";
  220. document.set(initialText);
  221. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  222. asList(new Perspectivation.ToLowerCase(6), new Perspectivation.Hide(0, 6)));
  223. position.notify(new DocumentEvent(), document);
  224. final Field isEnabledField = PerspectivationPosition.class.getDeclaredField("isEnabled");
  225. isEnabledField.setAccessible(true);
  226. isEnabledField.set(position, false);
  227. position.undoPerspectivation();
  228. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  229. }
  230. /**
  231. * All perspectivations are removed, even those not added by the position
  232. */
  233. @Test
  234. public void undoPerspectivationRemovesAllPerspectivations() throws Exception {
  235. final String initialText = "The Quick Brown Fox Is Slow Today.";
  236. document.set(initialText);
  237. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  238. asList(new Perspectivation.ToLowerCase(6), new Perspectivation.Hide(0, 6)));
  239. position.notify(new DocumentEvent(), document);
  240. position.undoPerspectivation();
  241. assertThat(document.get()).isEqualTo(initialText);
  242. }
  243. @Test
  244. public void undoRemovesToLowerCasePositionFromDocument() throws Exception {
  245. document.set("The Quick Brown Fox Is Slow Today.");
  246. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  247. asList(new Perspectivation.ToLowerCase(6)));
  248. position.notify(new DocumentEvent(), document);
  249. position.undoPerspectivation();
  250. assertThat(document.getMasterDocument().getPositions(TO_LOWER_CASE_CATEGORY)).isEmpty();
  251. }
  252. @Test
  253. public void undoRemovesHidePositionFromDocument() throws Exception {
  254. document.set("The Quick Brown Fox Is Slow Today.");
  255. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  256. asList(new Perspectivation.Hide(0, 6)));
  257. position.notify(new DocumentEvent(), document);
  258. position.undoPerspectivation();
  259. assertThat(document.getMasterDocument().getPositions(HIDE_CATEGORY)).isEmpty();
  260. }
  261. @Test
  262. public void undoRemovesToLowerCasePositionFromPerspectivationPosition() throws Exception {
  263. document.set("The Quick Brown Fox Is Slow Today.");
  264. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  265. asList(new Perspectivation.ToLowerCase(6)));
  266. position.notify(new DocumentEvent(), document);
  267. position.undoPerspectivation();
  268. assertThat(position.getToLowerCasePositions()).isEmpty();
  269. }
  270. @Test
  271. public void undoRemovesHidePositionFromPerspectivationPosition() throws Exception {
  272. document.set("The Quick Brown Fox Is Slow Today.");
  273. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  274. asList(new Perspectivation.Hide(0, 6)));
  275. position.notify(new DocumentEvent(), document);
  276. position.undoPerspectivation();
  277. assertThat(position.getHidePositions()).isEmpty();
  278. }
  279. @Test
  280. public void isPerspectivatedReturnsFalseAfterUndo() throws Exception {
  281. final String initialText = "The Quick Brown Fox Is Slow Today.";
  282. document.set(initialText);
  283. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true, emptyList());
  284. position.notify(new DocumentEvent(), document);
  285. position.undoPerspectivation();
  286. assertThat(position.isPerspectivated()).isFalse();
  287. }
  288. @Test
  289. public void perspectivationCanBeRepeatedAfterUndo() throws Exception {
  290. final String initialText = "The Quick Brown Fox Is Slow Today.";
  291. document.set(initialText);
  292. final PerspectivationPosition position = new PerspectivationPosition(4, 12, unused -> true,
  293. asList(new Perspectivation.ToLowerCase(6), new Perspectivation.Hide(0, 6)));
  294. position.notify(new DocumentEvent(), document);
  295. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  296. position.undoPerspectivation();
  297. // Repeated perspectivation
  298. position.notify(new DocumentEvent(), document);
  299. assertThat(document.get()).isEqualTo("The brown Fox Is Slow Today.");
  300. }
  301. @Test
  302. public void documentRetainsToLowerCaseOfUnaffectedPositionOnDeletion() throws Exception {
  303. document.set("The Quick Brown Fox Is Slow Today.");
  304. final PerspectivationPosition position = new PerspectivationPosition(19, 5, event -> true,
  305. asList(new Perspectivation.ToLowerCase(0)));
  306. originDocument.addPosition(PERSPECTIVATION_CATEGORY, position);
  307. position.notify(new DocumentEvent(document, 0, 0, ""), document);
  308. assertThat(document.getMasterDocument().getPositions(TO_LOWER_CASE_CATEGORY))
  309. .containsExactly(new ToLowerCasePosition(19));
  310. document.replace(4, 12, "");
  311. assertThat(document.getMasterDocument().getPositions(TO_LOWER_CASE_CATEGORY))
  312. .containsExactly(new ToLowerCasePosition(7));
  313. }
  314. // Removing to lower case and hidden document range for current position
  315. @Test
  316. public void documentRemovesToLowerCaseOfCurrentPositionOnDeletion() throws Exception {
  317. document.set("The Quick Brown Fox Is Slow Today.");
  318. final PerspectivationPosition position = new PerspectivationPosition(4, 12, event -> true,
  319. asList(new Perspectivation.ToLowerCase(6)));
  320. originDocument.addPosition(PERSPECTIVATION_CATEGORY, position);
  321. position.notify(new DocumentEvent(document, 0, 0, ""), document);
  322. assertThat(document.getMasterDocument().getPositions(TO_LOWER_CASE_CATEGORY))
  323. .containsExactly(new ToLowerCasePosition(10));
  324. document.replace(4, 12, "");
  325. assertThat(document.getMasterDocument().getPositions(TO_LOWER_CASE_CATEGORY)).isEmpty();
  326. }
  327. /**
  328. * It is assumed that hidden content was generated and is potentially invalid
  329. * when the perspectivation is undone.
  330. */
  331. @Test
  332. public void updaterRemovesHiddenDocumentRangeFromMasterDocumentForCurrentPositionOnDeletion() throws Exception {
  333. document.set("The Quick Brown Fox Is Slow Today.");
  334. final PerspectivationPosition position = new PerspectivationPosition(4, 12, event -> true,
  335. asList(new Perspectivation.Hide(0, 6)));
  336. originDocument.addPosition(PERSPECTIVATION_CATEGORY, position);
  337. position.notify(new DocumentEvent(document, 0, 0, ""), document); // trigger application of perspectivations
  338. assertThat(originDocument.getPositions(HIDE_CATEGORY)).containsExactly(new HidePosition(4, 6));
  339. assertThat(originDocument.get()).isEqualTo("The Quick Brown Fox Is Slow Today.");
  340. assertThat(document.get()).isEqualTo("The Brown Fox Is Slow Today.");
  341. originDocument.replace(4, 12, "");
  342. assertThat(originDocument.getPositions(HIDE_CATEGORY)).isEmpty();
  343. assertThat(originDocument.get()).isEqualTo("The Fox Is Slow Today.");
  344. assertThat(document.get()).isEqualTo("The Fox Is Slow Today.");
  345. }
  346. // Removing to lower case and hidden document range for previous position
  347. /**
  348. * It is assumed that hidden content was generated and is potentially invalid
  349. * when the perspectivation is undone.
  350. */
  351. @Test
  352. public void updaterInlinesToLowerCaseOfPreviousPositionIntoOriginDocumentOnDeletion() throws Exception {
  353. final String initialText = "The Quick Brown Fox Is Slow Today.";
  354. document.set(initialText);
  355. final PerspectivationPosition previousPosition = new PerspectivationPosition(4, 12, event -> true,
  356. asList(new Perspectivation.ToLowerCase(6)));
  357. originDocument.addPosition(PERSPECTIVATION_CATEGORY, previousPosition);
  358. previousPosition.notify(new DocumentEvent(document, 0, 0, ""), document);
  359. final PerspectivationPosition currentPosition = new PerspectivationPosition(16, 3, event -> true, emptyList());
  360. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  361. link(previousPosition, currentPosition);
  362. assertThat(originDocument.getPositions(TO_LOWER_CASE_CATEGORY)).containsExactly(new ToLowerCasePosition(10));
  363. assertThat(originDocument.get()).isEqualTo(initialText);
  364. assertThat(document.get()).isEqualTo("The Quick brown Fox Is Slow Today.");
  365. document.replace(16, 3, "");
  366. assertThat(originDocument.getPositions(TO_LOWER_CASE_CATEGORY)).isEmpty();
  367. final String lowerCasedShortenedText = "The Quick brown Is Slow Today.";
  368. assertThat(originDocument.get()).isEqualTo(lowerCasedShortenedText);
  369. assertThat(document.get()).isEqualTo(lowerCasedShortenedText);
  370. }
  371. @Test
  372. public void updaterDoesNotInlineToLowerCaseOfPreviousPositionIntoOriginDocumentOnDeletionIfThereAreSiblings()
  373. throws Exception {
  374. final String initialText = "The Quick Brown Fox Is Slow Today.";
  375. document.set(initialText);
  376. final PerspectivationPosition previousPosition = new PerspectivationPosition(4, 12, event -> true,
  377. asList(new Perspectivation.ToLowerCase(6)));
  378. originDocument.addPosition(PERSPECTIVATION_CATEGORY, previousPosition);
  379. previousPosition.notify(new DocumentEvent(document, 0, 0, ""), document);
  380. final PerspectivationPosition currentPosition = new PerspectivationPosition(16, 3, event -> true, emptyList());
  381. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  382. link(previousPosition, currentPosition);
  383. final PerspectivationPosition siblingPosition = new PerspectivationPosition(20, 2, event -> true, emptyList());
  384. originDocument.addPosition(PERSPECTIVATION_CATEGORY, siblingPosition);
  385. link(previousPosition, siblingPosition);
  386. assertThat(originDocument.getPositions(TO_LOWER_CASE_CATEGORY)).containsExactly(new ToLowerCasePosition(10));
  387. assertThat(originDocument.get()).isEqualTo(initialText);
  388. assertThat(document.get()).isEqualTo("The Quick brown Fox Is Slow Today.");
  389. document.replace(16, 3, "");
  390. assertThat(originDocument.getPositions(TO_LOWER_CASE_CATEGORY)).containsExactly(new ToLowerCasePosition(10));
  391. assertThat(originDocument.get()).isEqualTo("The Quick Brown Is Slow Today.");
  392. assertThat(document.get()).isEqualTo("The Quick brown Is Slow Today.");
  393. }
  394. /**
  395. * It is assumed that hidden content was generated and is potentially invalid
  396. * when the perspectivation is undone.
  397. */
  398. @Test
  399. public void updaterRemovesHiddenDocumentRangeFromMasterDocumentForPreviousPositionOnDeletion() throws Exception {
  400. document.set("The Quick Brown Fox Is Slow Today.");
  401. final int hideLength = 6;
  402. final PerspectivationPosition previousPosition = new PerspectivationPosition(4, 12, event -> true,
  403. asList(new Perspectivation.Hide(0, hideLength)));
  404. originDocument.addPosition(PERSPECTIVATION_CATEGORY, previousPosition);
  405. final PerspectivationPosition currentPosition = new PerspectivationPosition(16, 3, event -> true, emptyList());
  406. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  407. link(previousPosition, currentPosition);
  408. previousPosition.notify(new DocumentEvent(document, 0, 0, ""), document);
  409. assertThat(originDocument.getPositions(HIDE_CATEGORY)).containsExactly(new HidePosition(4, hideLength));
  410. document.replace(16 - hideLength, 3, "");
  411. assertThat(originDocument.getPositions(HIDE_CATEGORY)).isEmpty();
  412. assertThat(originDocument.get()).isEqualTo("The Brown Is Slow Today.");
  413. assertThat(document.get()).isEqualTo("The Brown Is Slow Today.");
  414. }
  415. @Test
  416. public void updaterDoesNotRemoveHiddenDocumentRangeFromMasterDocumentForPreviousPositionOnDeletionIfThereAreSiblings()
  417. throws Exception {
  418. document.set("The Quick Brown Fox Is Slow Today.");
  419. final int hideLength = 6;
  420. final PerspectivationPosition previousPosition = new PerspectivationPosition(4, 12, event -> true,
  421. asList(new Perspectivation.Hide(0, hideLength)));
  422. originDocument.addPosition(PERSPECTIVATION_CATEGORY, previousPosition);
  423. final PerspectivationPosition currentPosition = new PerspectivationPosition(16, 3, event -> true, emptyList());
  424. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  425. link(previousPosition, currentPosition);
  426. final PerspectivationPosition siblingPosition = new PerspectivationPosition(20, 2, event -> true, emptyList());
  427. originDocument.addPosition(PERSPECTIVATION_CATEGORY, siblingPosition);
  428. link(previousPosition, siblingPosition);
  429. previousPosition.notify(new DocumentEvent(document, 0, 0, ""), document);
  430. assertThat(originDocument.getPositions(HIDE_CATEGORY)).containsExactly(new HidePosition(4, hideLength));
  431. document.replace(16 - hideLength, 3, "");
  432. assertThat(originDocument.getPositions(HIDE_CATEGORY)).containsExactly(new HidePosition(4, hideLength));
  433. assertThat(originDocument.get()).isEqualTo("The Quick Brown Is Slow Today.");
  434. assertThat(document.get()).isEqualTo("The Brown Is Slow Today.");
  435. }
  436. @Test
  437. public void updaterRemovesPreviousPositionOnDeletion() throws Exception {
  438. document.set("The Quick Brown Fox Is Slow Today.");
  439. final PerspectivationPosition previousPosition = new PerspectivationPosition(4, 12, event -> true, emptyList());
  440. originDocument.addPosition(PERSPECTIVATION_CATEGORY, previousPosition);
  441. final PerspectivationPosition currentPosition = new PerspectivationPosition(16, 3, event -> true, emptyList());
  442. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  443. link(previousPosition, currentPosition);
  444. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).hasSize(2);
  445. document.replace(16, 3, "");
  446. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).isEmpty();
  447. }
  448. @Test
  449. public void updaterDoesNotRemovePreviousPositionOnDeletionIfThereAreSiblings() throws Exception {
  450. document.set("The Quick Brown Fox Is Slow Today.");
  451. final PerspectivationPosition previousPosition = new PerspectivationPosition(4, 12, event -> true, emptyList());
  452. originDocument.addPosition(PERSPECTIVATION_CATEGORY, previousPosition);
  453. final PerspectivationPosition currentPosition = new PerspectivationPosition(16, 3, event -> true, emptyList());
  454. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  455. link(previousPosition, currentPosition);
  456. final PerspectivationPosition siblingPosition = new PerspectivationPosition(20, 2, event -> true, emptyList());
  457. originDocument.addPosition(PERSPECTIVATION_CATEGORY, siblingPosition);
  458. link(previousPosition, siblingPosition);
  459. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).hasSize(3);
  460. document.replace(16, 3, "");
  461. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).containsExactly(previousPosition,
  462. siblingPosition);
  463. }
  464. // Removing to lower case and hidden document range for next position
  465. /**
  466. * It is assumed that hidden content was generated and is potentially invalid
  467. * when the perspectivation is undone.
  468. */
  469. @Test
  470. public void updaterInlinesToLowerCaseOfNextPositionIntoOriginDocumentOnDeletion() throws Exception {
  471. final String initialText = "The Quick Brown Fox Is Slow Today.";
  472. document.set(initialText);
  473. final PerspectivationPosition currentPosition = new PerspectivationPosition(0, 3, event -> true, emptyList());
  474. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  475. final PerspectivationPosition nextPosition = new PerspectivationPosition(4, 12, event -> true,
  476. asList(new Perspectivation.ToLowerCase(6)));
  477. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition);
  478. nextPosition.notify(new DocumentEvent(document, 0, 0, ""), document);
  479. link(currentPosition, nextPosition);
  480. assertThat(originDocument.getPositions(TO_LOWER_CASE_CATEGORY)).containsExactly(new ToLowerCasePosition(10));
  481. assertThat(originDocument.get()).isEqualTo(initialText);
  482. assertThat(document.get()).isEqualTo("The Quick brown Fox Is Slow Today.");
  483. document.replace(0, 3, "");
  484. final String lowerCasedAndShortenedText = " Quick brown Fox Is Slow Today.";
  485. assertThat(originDocument.getPositions(TO_LOWER_CASE_CATEGORY)).isEmpty();
  486. assertThat(originDocument.get()).isEqualTo(lowerCasedAndShortenedText);
  487. assertThat(document.get()).isEqualTo(lowerCasedAndShortenedText);
  488. }
  489. @Test
  490. public void updaterInlinesToLowerCasesOfNextPositionsIntoOriginDocumentOnDeletion() throws Exception {
  491. final String initialText = "The Quick Brown Fox Is Slow Today.";
  492. document.set(initialText);
  493. final PerspectivationPosition currentPosition = new PerspectivationPosition(0, 3, event -> true, emptyList());
  494. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  495. final PerspectivationPosition nextPosition1 = new PerspectivationPosition(4, 6, event -> true,
  496. asList(new Perspectivation.ToLowerCase(0)));
  497. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition1);
  498. nextPosition1.notify(new DocumentEvent(document, 0, 0, ""), document);
  499. link(currentPosition, nextPosition1);
  500. final PerspectivationPosition nextPosition2 = new PerspectivationPosition(10, 6, event -> true,
  501. asList(new Perspectivation.ToLowerCase(0)));
  502. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition2);
  503. nextPosition2.notify(new DocumentEvent(document, 0, 0, ""), document);
  504. link(currentPosition, nextPosition2);
  505. assertThat(originDocument.getPositions(TO_LOWER_CASE_CATEGORY)).containsExactly(new ToLowerCasePosition(4),
  506. new ToLowerCasePosition(10));
  507. assertThat(originDocument.get()).isEqualTo(initialText);
  508. assertThat(document.get()).isEqualTo("The quick brown Fox Is Slow Today.");
  509. document.replace(0, 3, "");
  510. final String lowerCasedAndShortenedText = " quick brown Fox Is Slow Today.";
  511. assertThat(originDocument.getPositions(TO_LOWER_CASE_CATEGORY)).isEmpty();
  512. assertThat(originDocument.get()).isEqualTo(lowerCasedAndShortenedText);
  513. assertThat(document.get()).isEqualTo(lowerCasedAndShortenedText);
  514. }
  515. /**
  516. * It is assumed that hidden content was generated and is potentially invalid
  517. * when the perspectivation is undone.
  518. */
  519. @Test
  520. public void updaterRemovesHiddenDocumentRangeFromMasterDocumentForNextPositionOnDeletion() throws Exception {
  521. document.set("The Quick Brown Fox Is Slow Today.");
  522. final PerspectivationPosition currentPosition = new PerspectivationPosition(4, 5, event -> true, emptyList());
  523. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  524. final int hideLength = 3;
  525. final PerspectivationPosition nextPosition = new PerspectivationPosition(16, 3, event -> true,
  526. asList(new Perspectivation.Hide(0, hideLength)));
  527. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition);
  528. link(currentPosition, nextPosition);
  529. nextPosition.notify(new DocumentEvent(document, 0, 0, ""), document);
  530. assertThat(originDocument.getPositions(HIDE_CATEGORY)).containsExactly(new HidePosition(16, hideLength));
  531. // This replacement triggers a registerPostNotificationReplace with the outdated
  532. // next position. However, the next position is updated before the post
  533. // notification replace is executed - then with the updated range.
  534. document.replace(4, 5, "");
  535. assertThat(originDocument.getPositions(HIDE_CATEGORY)).isEmpty();
  536. assertThat(originDocument.get()).isEqualTo("The Brown Is Slow Today.");
  537. assertThat(document.get()).isEqualTo("The Brown Is Slow Today.");
  538. }
  539. @Test
  540. public void updaterRemovesHiddenDocumentRangesFromMasterDocumentForNextPositionsOnDeletion() throws Exception {
  541. document.set("The Quick Brown Fox Is Slow Today.");
  542. final PerspectivationPosition currentPosition = new PerspectivationPosition(4, 5, event -> true, emptyList());
  543. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  544. final int hideLength1 = 3;
  545. final PerspectivationPosition nextPosition1 = new PerspectivationPosition(16, hideLength1, event -> true,
  546. asList(new Perspectivation.Hide(0, hideLength1)));
  547. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition1);
  548. link(currentPosition, nextPosition1);
  549. nextPosition1.notify(new DocumentEvent(document, 0, 0, ""), document);
  550. final int hideLength2 = 2;
  551. final PerspectivationPosition nextPosition2 = new PerspectivationPosition(20, hideLength2, event -> true,
  552. asList(new Perspectivation.Hide(0, hideLength2)));
  553. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition2);
  554. link(currentPosition, nextPosition2);
  555. nextPosition2.notify(new DocumentEvent(document, 0, 0, ""), document);
  556. assertThat(originDocument.getPositions(HIDE_CATEGORY)).containsExactly(new HidePosition(16, hideLength1),
  557. new HidePosition(20, hideLength2));
  558. // This replacement triggers a registerPostNotificationReplace with the outdated
  559. // next positions. However, the next positions are updated before the post
  560. // notification replace is executed - then with the updated range.
  561. document.replace(4, 5, "");
  562. assertThat(originDocument.getPositions(HIDE_CATEGORY)).isEmpty();
  563. assertThat(originDocument.get()).isEqualTo("The Brown Slow Today.");
  564. assertThat(document.get()).isEqualTo("The Brown Slow Today.");
  565. }
  566. @Test
  567. public void updaterRemovesBothCurrentAndNextPositionOnDeletionWithoutException() throws Exception {
  568. document.set("The Quick Brown Fox Is Slow Today.");
  569. final PerspectivationPosition currentPositionPosition = new PerspectivationPosition(4, 5, event -> true,
  570. emptyList());
  571. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPositionPosition);
  572. final int hideLength = 3;
  573. final PerspectivationPosition nextPosition = new PerspectivationPosition(16, hideLength, event -> true,
  574. asList(new Perspectivation.Hide(0, hideLength)));
  575. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition);
  576. link(currentPositionPosition, nextPosition);
  577. nextPosition.notify(new DocumentEvent(document, 0, 0, ""), document);
  578. assertThat(originDocument.getPositions(HIDE_CATEGORY)).containsExactly(new HidePosition(16, hideLength));
  579. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).hasSize(2);
  580. document.replace(4, 15, "");
  581. assertThat(originDocument.getPositions(HIDE_CATEGORY)).isEmpty();
  582. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).isEmpty();
  583. assertThat(originDocument.get()).isEqualTo("The Slow Today.");
  584. assertThat(document.get()).isEqualTo("The Slow Today.");
  585. }
  586. @Test
  587. public void updaterRemovesBothCurrentAndNextPositionsOnDeletionWithoutException() throws Exception {
  588. document.set("The Quick Brown Fox Is Slow Today.");
  589. final PerspectivationPosition currentPositionPosition = new PerspectivationPosition(4, 5, event -> true,
  590. emptyList());
  591. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPositionPosition);
  592. final int hideLength1 = 3;
  593. final PerspectivationPosition nextPosition1 = new PerspectivationPosition(16, hideLength1, event -> true,
  594. asList(new Perspectivation.Hide(0, hideLength1)));
  595. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition1);
  596. link(currentPositionPosition, nextPosition1);
  597. nextPosition1.notify(new DocumentEvent(document, 0, 0, ""), document);
  598. final int hideLength2 = 2;
  599. final PerspectivationPosition nextPosition2 = new PerspectivationPosition(20, hideLength2, event -> true,
  600. asList(new Perspectivation.Hide(0, hideLength2)));
  601. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition2);
  602. link(currentPositionPosition, nextPosition2);
  603. nextPosition2.notify(new DocumentEvent(document, 0, 0, ""), document);
  604. assertThat(originDocument.getPositions(HIDE_CATEGORY)).containsExactly(new HidePosition(16, hideLength1),
  605. new HidePosition(20, hideLength2));
  606. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).hasSize(3);
  607. document.replace(4, 18, "");
  608. assertThat(originDocument.getPositions(HIDE_CATEGORY)).isEmpty();
  609. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).isEmpty();
  610. assertThat(originDocument.get()).isEqualTo("The Today.");
  611. assertThat(document.get()).isEqualTo("The Today.");
  612. }
  613. @Test
  614. public void updaterRemovesNextPositionOnDeletion() throws Exception {
  615. document.set("The Quick Brown Fox Is Slow Today.");
  616. final PerspectivationPosition previousPosition = new PerspectivationPosition(4, 5, event -> true, emptyList());
  617. originDocument.addPosition(PERSPECTIVATION_CATEGORY, previousPosition);
  618. final PerspectivationPosition currentPosition = new PerspectivationPosition(16, 3, event -> true, emptyList());
  619. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  620. link(previousPosition, currentPosition);
  621. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).hasSize(2);
  622. document.replace(4, 5, "");
  623. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).isEmpty();
  624. }
  625. @Test
  626. public void updaterRemovesNextPositionsOnDeletion() throws Exception {
  627. document.set("The Quick Brown Fox Is Slow Today.");
  628. final PerspectivationPosition currentPosition = new PerspectivationPosition(4, 5, event -> true, emptyList());
  629. originDocument.addPosition(PERSPECTIVATION_CATEGORY, currentPosition);
  630. final PerspectivationPosition nextPosition1 = new PerspectivationPosition(16, 3, event -> true, emptyList());
  631. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition1);
  632. link(currentPosition, nextPosition1);
  633. final PerspectivationPosition nextPosition2 = new PerspectivationPosition(20, 3, event -> true, emptyList());
  634. originDocument.addPosition(PERSPECTIVATION_CATEGORY, nextPosition2);
  635. link(currentPosition, nextPosition2);
  636. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).hasSize(3);
  637. document.replace(4, 5, "");
  638. assertThat(originDocument.getPositions(PERSPECTIVATION_CATEGORY)).isEmpty();
  639. }
  640. private static class ListForTestingForEach<T> extends ArrayList<T> {
  641. private static final long serialVersionUID = 7919732490022687893L;
  642. private final Runnable runnableNotifiedOfForEach;
  643. public ListForTestingForEach(final Runnable runnableNotifiedOfForEach) {
  644. this.runnableNotifiedOfForEach = runnableNotifiedOfForEach;
  645. }
  646. @Override
  647. public void forEach(final Consumer<? super T> action) {
  648. runnableNotifiedOfForEach.run();
  649. super.forEach(action);
  650. }
  651. }
  652. }