Publish shared FXML diagnostics and integrate IntelliJ Problems
Navigate authoritative FXML locations, withdraw stale results and preserve host Undo/Redo. Include editor ownership in native problem identity so equal diagnostics from separate owners survive independent cleanup. Qualify both hosts automatically.
This commit is contained in:
@@ -82,6 +82,155 @@ public final class WorkflowProbe implements StartupActivity.DumbAware {
|
||||
});
|
||||
}
|
||||
|
||||
private static void checkProblems(
|
||||
Project project,
|
||||
VirtualFile file,
|
||||
DesignerPane pane,
|
||||
de.neitzel.fxdesigner.host.DocumentSession document)
|
||||
throws Exception {
|
||||
var original = document.snapshot().toCompletableFuture().get();
|
||||
String invalid = original.text().replace("path=\"home\"", "path=\"problemMissing\"");
|
||||
if (invalid.equals(original.text())) throw new AssertionError("Missing fixture binding");
|
||||
document
|
||||
.apply(
|
||||
new de.neitzel.fxdesigner.contracts.EditBatch(
|
||||
original.revision(),
|
||||
"Problem fixture",
|
||||
java.util.List.of(
|
||||
new de.neitzel.fxdesigner.contracts.EditBatch.Replacement(
|
||||
0, original.text().length(), invalid))))
|
||||
.toCompletableFuture()
|
||||
.get();
|
||||
await(
|
||||
() ->
|
||||
fx(
|
||||
() ->
|
||||
pane.lookupAll(".text-area").stream()
|
||||
.anyMatch(
|
||||
n ->
|
||||
n instanceof javafx.scene.control.TextArea t
|
||||
&& t.getText().equals(invalid))));
|
||||
fx(
|
||||
() -> {
|
||||
pane.lookupAll(".titled-pane").stream()
|
||||
.filter(
|
||||
n ->
|
||||
n instanceof javafx.scene.control.TitledPane t
|
||||
&& "Bindings".equals(t.getText()))
|
||||
.forEach(n -> ((javafx.scene.control.TitledPane) n).setExpanded(true));
|
||||
pane.lookupAll(".tab-pane").stream()
|
||||
.filter(n -> n instanceof javafx.scene.control.TabPane)
|
||||
.map(n -> (javafx.scene.control.TabPane) n)
|
||||
.forEach(
|
||||
t ->
|
||||
t.getTabs().stream()
|
||||
.filter(tab -> "Problems".equals(tab.getText()))
|
||||
.findFirst()
|
||||
.ifPresent(tab -> t.getSelectionModel().select(tab)));
|
||||
return null;
|
||||
});
|
||||
click(pane, "Validate View");
|
||||
var collector = com.intellij.analysis.problemsView.ProblemsCollector.getInstance(project);
|
||||
await(
|
||||
() ->
|
||||
edt(
|
||||
() ->
|
||||
collector.getFileProblems(file).stream()
|
||||
.anyMatch(p -> p.getText().contains("problemMissing"))));
|
||||
var problem =
|
||||
edt(
|
||||
() ->
|
||||
(com.intellij.analysis.problemsView.FileProblem)
|
||||
collector.getFileProblems(file).stream()
|
||||
.filter(p -> p.getText().contains("problemMissing"))
|
||||
.findFirst()
|
||||
.orElseThrow());
|
||||
int expectedOffset =
|
||||
edt(
|
||||
() -> {
|
||||
var d = FileDocumentManager.getInstance().getDocument(file);
|
||||
return d.getLineStartOffset(problem.getLine()) + problem.getColumn();
|
||||
});
|
||||
String declaration =
|
||||
invalid.substring(expectedOffset, invalid.indexOf('>', expectedOffset) + 1);
|
||||
if (!declaration.startsWith("<DirectBinding")
|
||||
|| !declaration.contains("path=\"problemMissing\""))
|
||||
throw new AssertionError(
|
||||
"Problems origin did not locate an affected binding: " + declaration);
|
||||
edt(
|
||||
() -> {
|
||||
var window =
|
||||
com.intellij.openapi.wm.ToolWindowManager.getInstance(project)
|
||||
.getToolWindow("Problems View");
|
||||
if (window == null) throw new AssertionError("Native Problems tool window missing");
|
||||
window.show();
|
||||
new OpenFileDescriptor(project, problem.getFile(), problem.getLine(), problem.getColumn())
|
||||
.navigate(true);
|
||||
return null;
|
||||
});
|
||||
await(
|
||||
() ->
|
||||
edt(
|
||||
() -> {
|
||||
var textEditor = FileEditorManager.getInstance(project).getSelectedTextEditor();
|
||||
return textEditor != null
|
||||
&& textEditor.getCaretModel().getOffset() == expectedOffset;
|
||||
}));
|
||||
if (!document.snapshot().toCompletableFuture().get().text().equals(invalid))
|
||||
throw new AssertionError("Problems navigation mutated source");
|
||||
document.undo().toCompletableFuture().get();
|
||||
await(
|
||||
() ->
|
||||
edt(
|
||||
() ->
|
||||
collector.getFileProblems(file).stream()
|
||||
.noneMatch(p -> p.getText().contains("problemMissing"))));
|
||||
if (!document.snapshot().toCompletableFuture().get().text().equals(original.text()))
|
||||
throw new AssertionError("Problems navigation changed undo history");
|
||||
// Observe the shared editor's Undo revision before issuing Redo; its previous invalid
|
||||
// text must not satisfy the Redo wait while the Undo notification is still queued.
|
||||
await(
|
||||
() ->
|
||||
fx(
|
||||
() ->
|
||||
pane.lookupAll(".text-area").stream()
|
||||
.anyMatch(
|
||||
n ->
|
||||
n instanceof javafx.scene.control.TextArea t
|
||||
&& t.getText().equals(original.text()))));
|
||||
document.redo().toCompletableFuture().get();
|
||||
await(
|
||||
() ->
|
||||
fx(
|
||||
() ->
|
||||
pane.lookupAll(".text-area").stream()
|
||||
.anyMatch(
|
||||
n ->
|
||||
n instanceof javafx.scene.control.TextArea t
|
||||
&& t.getText().equals(invalid))));
|
||||
click(pane, "Validate View");
|
||||
await(
|
||||
() ->
|
||||
edt(
|
||||
() ->
|
||||
collector.getFileProblems(file).stream()
|
||||
.anyMatch(p -> p.getText().contains("problemMissing"))));
|
||||
edt(
|
||||
() -> {
|
||||
FileEditorManager.getInstance(project).closeFile(file);
|
||||
return null;
|
||||
});
|
||||
await(
|
||||
() ->
|
||||
edt(
|
||||
() ->
|
||||
collector.getFileProblems(file).stream()
|
||||
.noneMatch(p -> "Neitzel FX Designer".equals(p.getGroup()))));
|
||||
System.out.println(
|
||||
"PASS native Problems: current validation, FXML origin/navigation, correction via Undo,"
|
||||
+ " redo validation and editor-close cleanup");
|
||||
}
|
||||
|
||||
public void runActivity(Project project) {
|
||||
if (!started.compareAndSet(false, true)) return;
|
||||
ApplicationManager.getApplication()
|
||||
@@ -238,6 +387,7 @@ public final class WorkflowProbe implements StartupActivity.DumbAware {
|
||||
try (var document =
|
||||
pane.kit().host().documents().open(path.toUri()).toCompletableFuture().get()) {
|
||||
de.neitzel.fxdesigner.kit.ProjectionHostChecks.run(pane, document);
|
||||
checkProblems(project, file, pane, document);
|
||||
}
|
||||
String version = fx(() -> System.getProperty("javafx.runtime.version"));
|
||||
if (!version.startsWith("26"))
|
||||
|
||||
Reference in New Issue
Block a user