113 lines
4.5 KiB
Java
113 lines
4.5 KiB
Java
package de.neitzel.fxdesigner.kit;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
import de.neitzel.fxdesigner.contracts.*;
|
|
import de.neitzel.fxdesigner.host.HostServices.*;
|
|
import de.neitzel.fxdesigner.protocol.BindingMetadata.Problem;
|
|
import java.net.URI;
|
|
import java.util.*;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
class DiagnosticActionsTest {
|
|
private static final String XML =
|
|
"<?neitzel-model app.Person?>\r\n"
|
|
+ "<?import de.neitzel.fx.view.*?><VBox"
|
|
+ " xmlns:fx='http://javafx.com/fxml/1'><fx:define><BindingList><!-- before"
|
|
+ " --><DirectBinding control='name' property='text' path='name' direction = 'bad'"
|
|
+ " extra='keep'/><!-- after --></BindingList></fx:define><Label fx:id='name'"
|
|
+ " text='bad'/></VBox>";
|
|
|
|
private DocumentSnapshot snapshot(String text, boolean writable) {
|
|
return new DocumentSnapshot(URI.create("file:/View.fxml"), 7, text, writable, true);
|
|
}
|
|
|
|
private Diagnostic direction(DocumentSnapshot d) {
|
|
return FxmlDiagnostics.local(d).stream()
|
|
.filter(p -> p.message().startsWith("Invalid or missing direction:"))
|
|
.findFirst()
|
|
.orElseThrow();
|
|
}
|
|
|
|
private String apply(DocumentSnapshot d, QuickFix fix) {
|
|
return new EditBatch(d.revision(), fix.label(), fix.edits()).applyTo(d);
|
|
}
|
|
|
|
@Test
|
|
void directionChoicesAreExplicitAndChangeOnlyTheAttributeValue() {
|
|
var d = snapshot(XML, true);
|
|
var problem = direction(d);
|
|
assertEquals(
|
|
"bad",
|
|
XML.substring(problem.range().orElseThrow().start(), problem.range().orElseThrow().end()));
|
|
assertEquals(3, problem.fixes().size());
|
|
for (var fix : problem.fixes()) {
|
|
String value = fix.label().substring(fix.label().lastIndexOf(' ') + 1);
|
|
assertEquals(XML.replace("direction = 'bad'", "direction = '" + value + "'"), apply(d, fix));
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void missingAndEmptyDirectionKeepSourceAndHighlightAnActualRange() {
|
|
for (String text :
|
|
List.of(XML.replace(" direction = 'bad'", ""), XML.replace("'bad' extra", "'' extra"))) {
|
|
var d = snapshot(text, true);
|
|
var p = direction(d);
|
|
assertTrue(p.range().orElseThrow().end() > p.range().orElseThrow().start());
|
|
String fixed = apply(d, p.fixes().getFirst());
|
|
assertTrue(fixed.contains("<!-- before -->"));
|
|
assertTrue(fixed.contains("extra='keep'"));
|
|
assertFalse(
|
|
FxmlDiagnostics.local(snapshot(fixed, true)).stream()
|
|
.anyMatch(x -> x.message().startsWith("Invalid or missing direction:")));
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void duplicateRemovalPreservesFirstDeclarationAndSurroundingComments() {
|
|
String declaration = "<ComputedBinding control='name' property='text' method='#name'/>";
|
|
String text =
|
|
XML.replace("'bad' extra", "'view' extra")
|
|
.replace("<!-- after -->", "<!-- after -->" + declaration + "<!-- end -->");
|
|
var d = snapshot(text, true);
|
|
var p =
|
|
FxmlDiagnostics.local(d).stream()
|
|
.filter(x -> x.message().startsWith("Duplicate binding target:"))
|
|
.findFirst()
|
|
.orElseThrow();
|
|
assertEquals(text.replace(declaration, ""), apply(d, p.fixes().getFirst()));
|
|
}
|
|
|
|
@Test
|
|
void targetFixesRequireKnownSimpleDeclarationsAndNeverRemoveControls() {
|
|
var p = new Problem("name", "text", "ERROR", "unknown path");
|
|
var d = snapshot(XML, true);
|
|
assertEquals(1, FxmlDiagnostics.target(d, List.of(p)).getFirst().fixes().size());
|
|
for (String text :
|
|
List.of(
|
|
XML.replace("extra='keep'", "fx:id='binding'"),
|
|
XML.replace(
|
|
"extra='keep'/>", "extra='keep'><converter>app.C</converter></DirectBinding>"),
|
|
XML.replace("DirectBinding", "app.UnknownBinding")))
|
|
assertTrue(
|
|
FxmlDiagnostics.target(snapshot(text, true), List.of(p)).getFirst().fixes().isEmpty());
|
|
assertTrue(
|
|
FxmlDiagnostics.target(d, List.of(new Problem("name", "text", "WARNING", "unverified")))
|
|
.getFirst()
|
|
.fixes()
|
|
.isEmpty());
|
|
}
|
|
|
|
@Test
|
|
void readOnlyAndStaleSourceCannotApplyFixes() {
|
|
assertTrue(direction(snapshot(XML, false)).fixes().isEmpty());
|
|
var d = snapshot(XML, true);
|
|
var fix = direction(d).fixes().getFirst();
|
|
var edit = new EditBatch(d.revision(), fix.label(), fix.edits());
|
|
assertThrows(
|
|
ConcurrentModificationException.class,
|
|
() -> edit.applyTo(new DocumentSnapshot(d.document(), 8, XML, true, true)));
|
|
assertThrows(IllegalStateException.class, () -> edit.applyTo(snapshot(XML, false)));
|
|
}
|
|
}
|