Files
NeitzelFXDesigner/designer-intellij/src/test/java/de/neitzel/fxdesigner/intellij/IntellijDocumentsTest.java
T

163 lines
7.2 KiB
Java

package de.neitzel.fxdesigner.intellij;
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
import de.neitzel.fxdesigner.contracts.*;
import java.nio.file.*;
import java.util.*;
public final class IntellijDocumentsTest extends BasePlatformTestCase {
public void testNativeDocumentTransactionUndoAndIndependentHandles() throws Exception {
Path file = Files.createTempFile("designer-document-", ".fxml");
Files.writeString(file, "abcdef");
com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess.allowRootAccess(
getTestRootDisposable(), file.toRealPath().toString());
try (var docs = new IntellijDocuments(getProject())) {
var a = docs.open(file.toUri()).toCompletableFuture().get();
var b = docs.open(file.toUri()).toCompletableFuture().get();
var initial = a.snapshot().toCompletableFuture().get();
var changed =
a.apply(
new EditBatch(
initial.revision(),
"Component properties",
List.of(
new EditBatch.Replacement(0, 1, "A"),
new EditBatch.Replacement(5, 6, "F"))))
.toCompletableFuture()
.get();
assertEquals("AbcdeF", b.snapshot().toCompletableFuture().get().text());
a.close();
var undone = b.undo().toCompletableFuture().get();
assertEquals("abcdef", undone.text());
assertTrue(undone.revision() > changed.revision());
try {
b.apply(new EditBatch(initial.revision(), "stale", List.of())).toCompletableFuture().get();
fail("Stale edit accepted");
} catch (java.util.concurrent.ExecutionException expected) {
assertInstanceOf(expected.getCause(), ConcurrentModificationException.class);
}
var redone = b.redo().toCompletableFuture().get();
assertEquals("AbcdeF", redone.text());
b.save(redone.revision()).toCompletableFuture().get();
assertEquals("AbcdeF", Files.readString(file));
b.close();
} finally {
Files.deleteIfExists(file);
}
}
public void testExternalChangesDoNotLoseDraft() throws Exception {
Path file = Files.createTempFile("designer-conflict-", ".fxml");
Files.writeString(file, "old");
com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess.allowRootAccess(
getTestRootDisposable(), file.toRealPath().toString());
try (var docs = new IntellijDocuments(getProject())) {
var d = docs.open(file.toUri()).toCompletableFuture().get();
var changed =
d.apply(new EditBatch(0, "edit", List.of(new EditBatch.Replacement(0, 3, "draft"))))
.toCompletableFuture()
.get();
Files.writeString(file, "external");
try {
d.save(changed.revision()).toCompletableFuture().get();
fail("Conflict accepted");
} catch (java.util.concurrent.ExecutionException expected) {
assertInstanceOf(expected.getCause(), ConcurrentModificationException.class);
}
assertEquals("draft", d.snapshot().toCompletableFuture().get().text());
assertEquals("external", Files.readString(file));
d.close();
} finally {
Files.deleteIfExists(file);
}
}
public void testKeepsNativeDocumentOpenedThroughAlias() throws Exception {
Path directory = Files.createTempDirectory("designer-alias-");
Path real = directory.resolve("real");
Files.createDirectory(real);
Path alias = directory.resolve("alias");
Files.createSymbolicLink(alias, real);
Path file = real.resolve("View.fxml");
Files.writeString(file, "before");
com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess.allowRootAccess(
getTestRootDisposable(), directory.toRealPath().toString(), directory.toString());
var virtual =
com.intellij.openapi.vfs.LocalFileSystem.getInstance()
.refreshAndFindFileByNioFile(alias.resolve("View.fxml"));
var nativeDocument =
com.intellij.openapi.fileEditor.FileDocumentManager.getInstance().getDocument(virtual);
try (var docs = new IntellijDocuments(getProject());
var handle = docs.open(alias.resolve("View.fxml").toUri()).toCompletableFuture().get()) {
var before = handle.snapshot().toCompletableFuture().get();
var after =
handle
.apply(
new EditBatch(
before.revision(),
"Alias edit",
List.of(new EditBatch.Replacement(0, before.text().length(), "after"))))
.toCompletableFuture()
.get();
assertEquals("after", nativeDocument.getText());
assertEquals(file.toRealPath().toUri(), after.document());
handle.save(after.revision()).toCompletableFuture().get();
} finally {
Files.deleteIfExists(alias);
Files.deleteIfExists(file);
Files.deleteIfExists(real);
Files.deleteIfExists(directory);
}
}
public void testCleanExternalReloadAndRangeCaretPreservation() throws Exception {
Path file = Files.createTempFile("designer-reload-", ".fxml");
Files.writeString(file, "prefix value suffix");
com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess.allowRootAccess(
getTestRootDisposable(), file.toRealPath().toString());
try (var docs = new IntellijDocuments(getProject());
var handle = docs.open(file.toUri()).toCompletableFuture().get()) {
var initial = handle.snapshot().toCompletableFuture().get();
Files.writeString(file, "prefix external suffix");
var current = handle.snapshot().toCompletableFuture().get();
assertEquals("prefix external suffix", current.text());
assertFalse(current.dirty());
assertTrue(initial.revision() != current.revision());
var vf =
com.intellij.openapi.vfs.LocalFileSystem.getInstance().refreshAndFindFileByNioFile(file);
var document =
com.intellij.openapi.fileEditor.FileDocumentManager.getInstance().getDocument(vf);
var editor =
com.intellij.openapi.editor.EditorFactory.getInstance()
.createEditor(document, getProject());
try {
editor.getCaretModel().moveToOffset(current.text().length());
editor
.getSelectionModel()
.setSelection(current.text().indexOf("suffix"), current.text().length());
var updated =
handle
.apply(
new EditBatch(
current.revision(),
"Range edit",
List.of(new EditBatch.Replacement(7, 15, "X"))))
.toCompletableFuture()
.get();
assertEquals("prefix X suffix", updated.text());
assertEquals("suffix", editor.getSelectionModel().getSelectedText());
assertEquals(updated.text().length(), editor.getCaretModel().getOffset());
com.intellij.openapi.fileEditor.FileDocumentManager.getInstance().saveDocument(document);
var saved = handle.snapshot().toCompletableFuture().get();
assertEquals(updated.revision(), saved.revision());
assertFalse(saved.dirty());
handle.save(updated.revision()).toCompletableFuture().get();
} finally {
com.intellij.openapi.editor.EditorFactory.getInstance().releaseEditor(editor);
}
} finally {
Files.deleteIfExists(file);
}
}
}