[xml] WEB-70097 "Surround With" fails if the selection includes a trailing line break

GitOrigin-RevId: 8bc92ae304c782a799d0155d8ef3c663f6ff8420
This commit is contained in:
Piotr Tomiak
2025-09-11 12:03:35 +02:00
committed by intellij-monorepo-bot
parent 98f21f2918
commit afec56bb4b
2 changed files with 43 additions and 5 deletions

View File

@@ -88,10 +88,10 @@ public final class SurroundWithHandler implements CodeInsightActionHandler {
/**
* Invoke the surrounder directly without showing a UI. Does nothing if the supplied surrounder is not applicable at a given point.
*
*
* @param project context project
* @param editor editor to show the UI in, based on the caret positions
* @param file PSI file
* @param file PSI file
* @param surrounder template surrounder. The available surrounder of a given type will be executed.
*/
@TestOnly
@@ -277,7 +277,6 @@ public final class SurroundWithHandler implements CodeInsightActionHandler {
@NotNull Editor editor,
@NotNull PsiFile file,
@NotNull Map<Surrounder, PsiElement[]> surrounders) {
if (surrounders.isEmpty()) return null;
List<AnAction> applicable = new ArrayList<>();
Set<Character> usedMnemonicsSet = new HashSet<>();

View File

@@ -6,6 +6,12 @@ import com.intellij.codeInsight.template.impl.InvokeTemplateAction;
import com.intellij.codeInsight.template.impl.SurroundWithTemplateHandler;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.ui.UiInterceptors;
import com.intellij.ui.popup.PopupFactoryImpl;
import com.intellij.ui.popup.list.ListPopupModel;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
@@ -57,19 +63,52 @@ public class XmlSurroundWithTest extends MarkupSurroundTestBase {
public void testSurroundWithTagFirstElement() {
myFixture.configureByFile(BASE_PATH + "tag/Xml.xml");
AnAction firstAction = SurroundWithTemplateHandler.createActionGroup(myFixture.getEditor(), myFixture.getFile(), new HashSet<>()).get(0);
AnAction firstAction =
SurroundWithTemplateHandler.createActionGroup(myFixture.getEditor(), myFixture.getFile(), new HashSet<>()).get(0);
assertInstanceOf(firstAction, InvokeTemplateAction.class);
TemplateImpl template = ((InvokeTemplateAction)firstAction).getTemplate();
assertEquals("T", template.getKey());
}
public void testSurroundWithAction() throws InterruptedException {
myFixture.configureByText("foo.html", "<selection>some text</selection>");
myFixture.performEditorAction("SurroundWith");
var ref = new Ref<PopupFactoryImpl.ActionGroupPopup>();
UiInterceptors.register(new UiInterceptors.UiInterceptor<>(PopupFactoryImpl.ActionGroupPopup.class) {
@Override
protected void doIntercept(PopupFactoryImpl.@NotNull ActionGroupPopup component) {
ref.set(component);
}
});
var startTime = System.currentTimeMillis();
while (ref.isNull()) {
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
//noinspection BusyWait
Thread.sleep(1);
if (startTime + 5000 < System.currentTimeMillis()) {
throw new AssertionError("Popup not shown");
}
}
try {
var model = (ListPopupModel<?>)ref.get().getList().getModel();
for (int i = 0; i < model.getSize(); i++) {
if (model.getElementAt(i).toString().contains("Surround with <tag></tag>")) {
return;
}
}
throw new AssertionError("Surround with <tag></tag> action not found");
} finally {
Disposer.dispose(ref.get());
}
}
private void doHtmlSurroundWithTagViaSurroundPopup(String tag) {
String baseName = getBaseName("tag");
myFixture.configureByFile(baseName + ".html");
List<AnAction> actions = SurroundWithHandler.buildSurroundActions(getProject(), myFixture.getEditor(), myFixture.getFile());
Optional<InvokeTemplateAction> surroundWithTagAction = actions.stream()
.filter(it -> it instanceof InvokeTemplateAction)
.map(it -> (InvokeTemplateAction) it)
.map(it -> (InvokeTemplateAction)it)
.filter(it -> it.getTemplateText().toLowerCase(Locale.ROOT).contains("surround with <tag>"))
.findFirst();
assertTrue(surroundWithTagAction.isPresent());