/* * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.codeInsight; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.intellij.lang.annotations.Language; import org.intellij.lang.regexp.inspection.AnonymousGroupInspection; import org.jetbrains.annotations.NotNull; /** * @author Bas Leijdekkers */ @SuppressWarnings("Annotator") public class RegExpHighlightingTest extends LightCodeInsightFixtureTestCase { public void testAnonymousCapturingGroupInspection() { myFixture.enableInspections(new AnonymousGroupInspection()); doTest("(moo)\\1"); } public void testSingleRepetition() { doTest("a{1}"); } public void testRedundantEscape1() { doTest("\\;"); } public void testBoundaries() { doTest("\\b \\b{g} \\B \\A \\z \\Z \\G"); IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_9, myFixture.getModule(), myFixture.getTestRootDisposable()); doTest("\\b \\b{g} \\B \\A \\z \\Z \\G"); } public void testSimplifiableRange1() { doTest("a{0,1}"); } public void testSimplifiableRange2() { doTest("a{1,}"); } public void testSimplifiableRange3() { doTest("a{0,}"); } public void testFixedRepetitionRange() { doTest("a{3,3}"); } public void testDuplicateCharacterClass() { doTest("[\\w-\\w]"); } public void testNoRange() { doTest("[\\w-a]"); } public void testUnicodeGrapheme() { doTest("\\X"); IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_9, myFixture.getModule(), myFixture.getTestRootDisposable()); doTest("\\X"); } public void testRedundantEscape2() { doTest("\\-[\\*\\-\\[\\]\\\\\\+]"); } public void testBoundaryInsideCharacterClass() { doTest("[\\b]"); } public void testEmptyGroup1() { doTest("()"); } public void testEmptyGroup2() { doTest("(|)"); } public void testRedundantGroup() { doTest("((a))"); } public void testNamedGroup() { doTest("(?[a-c])\\1"); } public void testNamedGroupReference() { doTest("(?;[a-c])\\k"); } public void testUnresolvedNamedGroupReference() { doTest("\\k<adsf>"); } public void testInvalidGroupName() { doTest("(?<important_value1>\\d\\d)"); } public void testValidGroupName() { doTest("(?\\d\\d)"); } public void testRedundantCharacterRange() { doTest("[a-a]"); } public void testIllegalCharacterRange1() { doTest("[\\x4a-\\x3f]"); } public void testIllegalCharacterRange2() { doTest("[\\udbff\\udfff-\\ud800\\udc00]"); } public void testIllegalCharacterRange3() { doTest("[z-a]"); } public void testIllegalCharacterRange4() { IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_9, myFixture.getModule(), myFixture.getTestRootDisposable()); doTest("[\\N{LATIN SMALL LETTER Z}-\\N{LATIN SMALL LETTER A}]"); } public void testLegalCharacterRange() { // Cyrillic Capital Letter Zemlya - Unicode Han Character 'to peel, pare' (Unicode Supplementary Character) // without code point support 0x20731 wraps to 0x731 which would produce a "Illegal character range (to < from)" error doTest("[\\x{A640}-\\x{20731}]"); } public void testQuoted() { doTest("[\\Qabc?*+.))]][]\\E]"); } public void testValidDanglingMetacharacters() { doTest("]}"); } public void testRedundantlyEscapedClosingBrace() { doTest("\\]\\}"); } public void testBadEscape1() { doTest("\\q"); } public void testBadEscape2() { doTest("\\"); } public void testBadEscape3() { doTest("\\E"); } public void testBackspaceChar() { doTest("\\x08"); } public void testUnicodeEscape() { doTest("\\x{100000}"); } public void testBadUnicodeEscape() { doTest("\\x{1000000}"); } public void testProperty1() { doTest("^\\p{javaJavaIdentifierStart}+\\p{javaJavaIdentifierPart}+$"); } public void testProperty2() { doTest("\\p{InArabiC}\\p{IsTitleCase}\\p{IsAlphabetic}\\p{all}\\p{IsGreeK}"); } public void testPosixCharacterClass() { // posix character classes are not available in java regex patterns doTest("[:xdigit:]+"); } public void testNestedBackReference() { doTest("([ab]+=\\1)"); } public void testNoNPE() { doTest("(\");}}//"); } public void testBadInlineOption() { doTest("(?iZm)abc"); } public void testEscapedWhitespace() { doTest("a\\ b\\ c"); } public void testEscapedWhitespaceCommentMode() { doTest("(?x)a\\ b\\ c"); } public void testCountedQuantifier() { doTest("a{2147483647}"); doTest("a{2147483648}"); doTest("a{ max)\">1,0}"); doTest("a{,}"); } public void testOptions() { doTest("(?i)+"); doTest("(?i)*"); doTest("(?i){5,6}"); } public void testLookbehind() { doTest("(?*)"); doTest("(?+)"); doTest("(?\\1)"); } private void doTest(@Language("RegExp") String code) { code = StringUtil.escapeBackSlashes(code); myFixture.configureByText(JavaFileType.INSTANCE, "class X {{ java.util.regex.Pattern.compile(\"" + code + "\"); }}"); myFixture.testHighlighting(); } @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { return JAVA_8; } }