void () { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('{'); } public void testStartStringTemplateEof() { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('{'); } public void testStartStringTemplateNoClosingQuote() { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('{'); } public void testStartStringTemplateTextBlock() { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('{'); } public void testStartStringTemplateAlreadyBrace() { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('{'); } public void testEndStringTemplate() { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('}'); } public void testEndStringTemplateTextBlock() { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('}'); } public void testEndSecondStringTemplateTextBlock() { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('}'); } public void testEndSecondStringTemplateNonEmptyExpression() { setLanguageLevel(LanguageLevel.JDK_21_PREVIEW); doTest('}'); } protected void setLanguageLevel(@NotNull LanguageLevel level) { LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(getProject()); LanguageLevel prev = extension.getLanguageLevel(); extension.setLanguageLevel(level); Disposer.register(myFixture.getTestRootDisposable(), () -> extension.setLanguageLevel(prev)); } protected void doTest(char c) { myFixture.configureByFile(getTestName(true) + "_before.java"); myFixture.type(c); myFixture.checkResultByFile(getTestName(true) + "_after.java"); } protected void doTestUndo() { TextEditor fileEditor = TextEditorProvider.getInstance().getTextEditor(myFixture.getEditor()); UndoManager.getInstance(getProject()).undo(fileEditor); myFixture.checkResultByFile(getTestName(true) + "_afterUndo.java"); } private void doMultiTypeTest(char c) { myFixture.configureByFile(getTestName(true) + "_before.java"); List<Integer> whereToType = findWhereToType(myFixture.getEditor().getDocument().getImmutableCharSequence()); assertNotNull("Test file must have at least one place where to type!", whereToType); assertFalse("Test file must have at least one place where to type!", whereToType.isEmpty()); for (Integer offset : whereToType) { myFixture.getEditor().getCaretModel().moveToOffset(offset); myFixture.type(c); } myFixture.checkResultByFile(getTestName(true) + "_after.java"); } @Override protected String getTestDataPath() { return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/java/java-tests/testData/codeInsight/typing"; } private static List<Integer> findWhereToType(@NotNull CharSequence content) { List<Integer> offsets = new ArrayList<>(); Matcher m = Pattern.compile("/\\*typehere\\*/").matcher(content); while (m.find()) { offsets.add(m.end()); } offsets.sort(Comparator.reverseOrder()); return offsets; } }