The purpose of this document is to collect all inspection that are created during the tutorials on IJnspector mainly because WordPress keeps resolving unicode entities that shouldn't be resolved in order to users be able to copy and paste these inspections into their project files.
2020.04.09. - Validating ImageComparison setter method default values
<searchConfiguration name="ImageComparion setter method is defined with default value. That setter has no effect." text="$ImageComparison$.$setterMethod$($setValue$);" recursive="true" caseInsensitive="true" type="JAVA" pattern_context="default">
<constraint name="__context__" script=""import com.intellij.psi.*; def setterDefaults = [setPixelToleranceLevel: 0.1f, setThreshold: 5, setRectangleLineWidth: 1, setMinimalRectangleSize: 1, setMaximalRectangleCount: -1, setDrawExcludedRectangles: false] PsiExpression methodCall = setterMethod; //PsiExpression is the closest common superclass of PsiMethodCallExpression and PsiReferenceExpression //This iterates through the method call in a reverse order, from the last to the first while (methodCall instanceof PsiMethodCallExpression) { 	def methodName = methodNameOf(methodCall) 	//Ignoring non-setter methods in the call chain, e.g. imageComparison.setRectangleLineWidth(1).compareImages(); 	if (!methodName.startsWith("set") || !hasParameterDefined(methodCall) || !isFirstParamLiteral(methodCall)) { 		methodCall = methodCall.firstChild?.firstChild 		continue 	} 	def methodParamValue = methodParamValueOf(methodCall) 	if (methodParamValue == setterDefaults[methodName]) { 		return true 	} 	methodCall = methodCall.firstChild?.firstChild //firstChild: PsiReferenceExpression, firstChild.firstChild: PsiMethodCallExpression } return false //fallback return value String methodNameOf(PsiMethodCallExpression expr) { 	expr.firstChild.referenceName //firstChild: PsiReferenceExpression } boolean hasParameterDefined(PsiMethodCallExpression expr) { 	expr.lastChild.expressions.length > 0 } boolean isFirstParamLiteral(PsiMethodCallExpression expr) { 	expr.lastChild.expressions[0] instanceof PsiLiteralExpression } Object methodParamValueOf(PsiMethodCallExpression expr) { 	expr.lastChild.expressions[0].value //lastChild: PsiExpressionList, lastChild.expressions[0]: PsiLiteralExpression }"" within="" contains="" />
<constraint name="ImageComparison" nameOfExprType="com\.github\.romankh3\.image\.comparison\.ImageComparison" expressionTypes="com.github.romankh3.image.comparison.ImageComparison" within="" contains="" />
<constraint name="setValue" minCount="0" maxCount="2147483647" within="" contains="" />
<constraint name="setterMethod" within="" contains="" />
</searchConfiguration>
2019.12.03 - Iterate through methods of a superclass
<searchConfiguration name="Classes defining Step Definitions or hooks are not allowed to be extended." text="class $Class$ extends $Parent$ {}" recursive="true" caseInsensitive="true" type="JAVA" pattern_context="default">
<constraint name="__context__" script=""import com.intellij.psi.* def stepAnnotations = ["cucumber.api.java.en.Given", "cucumber.api.java.en.When", "cucumber.api.java.en.Then","cucumber.api.java.en.And", "cucumber.api.java.en.But", "io.cucumber.java.en.Given", "io.cucumber.java.en.When", "io.cucumber.java.en.Then", "io.cucumber.java.en.And", "io.cucumber.java.en.But"] PsiElement superclass = Parent.resolve(); if (superclass instanceof PsiClass) { 	for (PsiMethod method : superclass.getMethods()) { 		for (PsiAnnotation methodAnnotation : method.getAnnotations()) { 			if (stepAnnotations.contains(methodAnnotation.getQualifiedName())) { 				return true 			} 		} 	} } false"" within="" contains="" />
<constraint name="Class" within="" contains="" />
<constraint name="Parent" target="true" within="" contains="" />
</searchConfiguration>
<searchConfiguration name="FluentPage.hasExpectedUrl() call is not valid without @PageUrl annotation." text=" org.fluentlenium.assertj.FluentLeniumAssertions.assertThat($FluentPage$).hasExpectedUrl();" recursive="true" caseInsensitive="true" type="JAVA">
<constraint name="__context__" within="" contains="" />
<constraint name="FluentPage" script=""!FluentPage.getType().resolve().hasAnnotation("org.fluentlenium.core.annotation.PageUrl")"" nameOfExprType="org\.fluentlenium\.core\.FluentPage" expressionTypes="org.fluentlenium.core.FluentPage" exprTypeWithinHierarchy="true" within="" contains="" />
</searchConfiguration>
2019.03.25 - Mockito cannot mock/spy final classes
<searchConfiguration name="Mockito cannot mock/spy final classes." text="class $Class$ { @$MockAnnotation$( ) @Modifier("Instance") $FieldType$ $Field$ = $Init$; }" recursive="true" caseInsensitive="true" type="JAVA">
<constraint name="__context__" within="" contains="" />
<constraint name="Class" within="" contains="" />
<constraint name="FieldType" within="" contains="" />
<constraint name="Field" script=""Field.getType().resolve().hasModifierProperty("final")"" maxCount="2147483647" target="true" within="" contains="" />
<constraint name="Init" minCount="0" maxCount="0" within="" contains="" />
<constraint name="MockAnnotation" regexp="org\.mockito\.(Mock|Spy)" within="" contains="" />
</searchConfiguration>
<replaceConfiguration name="Retry count is greater than the max allowed (5). Apply quick fix to use the max allowed value." text="@picimako.tutorial.annotation.Retry(times = $RetryCount$)" recursive="true" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" useStaticImport="true" replacement="@picimako.tutorial.annotation.Retry(times = 5)">
<constraint name="__context__" within="" contains="" />
<constraint name="RetryCount" script=""RetryCount.text.toInteger() > 5"" within="" contains="" />
</replaceConfiguration>
<searchConfiguration name="Retry count is greater than the max allowed (5)." text="@picimako.tutorial.annotation.Retry(times = $RetryCount$)" recursive="true" caseInsensitive="true" type="JAVA">
<constraint name="__context__" within="" contains="" />
<constraint name="RetryCount" script=""RetryCount.text.toInteger() > 5"" within="" contains="" />
</searchConfiguration>
2018.12.28. - Lombok @NonNull annotation is used on a method parameter
<searchConfiguration name="Lombok @NonNull is used on a method parameter. You may replace it with an explicit check e.g. java.util.Objects.requireNonNull." text="$ReturnType$ $Method$(@$NonNullAnnotation$ () $ParameterType$ $Parameter$);" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="ReturnType" within="" contains="" />
<constraint name="Method" within="" contains="" />
<constraint name="ParameterType" maxCount="2147483647" within="" contains="" />
<constraint name="Parameter" maxCount="2147483647" target="true" within="" contains="" />
<constraint name="NonNullAnnotation" regexp="lombok\.NonNull" maxCount="2147483647" within="" contains="" />
</searchConfiguration>
2018.12.22. - Primitive type field, method parameter or local variable is annotated as Lombok @NonNull
<searchConfiguration name="Primitive type field, method parameter or local variable is annotated as Lombok @NonNull." text="@$NonNullAnnotation$ ( ) $Type$ $Name$ = $Init$;" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="NonNullAnnotation" regexp="lombok\.NonNull" within="" contains="" />
<constraint name="Init" minCount="0" within="" contains="" />
<constraint name="Type" regexp="byte|short|int|long|float|double|boolean|char" within="" contains="" />
<constraint name="Name" target="true" within="" contains="" />
</searchConfiguration>
<searchConfiguration name="@NonNull annotation is applied to a @Singular field. @Singular fields have no way to be set as null." text="@$BuilderAnnotation$( ) class $Class$ { @$SingularAnnotation$( ) @$NonNullAnnotation$( ) @Modifier("Instance") $FieldType$ $Field$ = $Init$; }" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="Class" within="" contains="" />
<constraint name="BuilderAnnotation" regexp="lombok\.Builder" within="" contains="" />
<constraint name="FieldType" maxCount="2147483647" within="" contains="" />
<constraint name="Field" maxCount="2147483647" target="true" within="" contains="" />
<constraint name="Init" minCount="0" within="" contains="" />
<constraint name="SingularAnnotation" regexp="lombok\.Singular" within="" contains="" />
<constraint name="NonNullAnnotation" regexp="lombok\.NonNull" within="" contains="" />
</searchConfiguration>
<searchConfiguration name="Explicit @Singular field initialization as empty collection can be removed, @Singular itself initializes it as an empty collection." text="@$BuilderAnnotation$( ) class $Class$ { @$SingularAnnotation$( ) @$BuilderDefaultAnnotation$( ) @Modifier("Instance") $FieldType$ $Field$ = $Init$; }" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="SingularAnnotation" regexp="lombok\.Singular" within="" contains="" />
<constraint name="BuilderDefaultAnnotation" regexp="lombok\.Builder\.Default" within="" contains="" />
<constraint name="FieldType" regexp="(java\.util\.(List|ArrayList|Iterable|Collection|((Sorted|Navigable|Hash|Tree|)(Set|Map))))|(com\.google\.common\.collect\.Immutable(Collection|List|Set|SortedSet|Map|BiMap|SortedMap|Table))" maxCount="2147483647" within="" contains="" />
<constraint name="Field" maxCount="2147483647" target="true" within="" contains="" />
<constraint name="Init" regexp="(new (ArrayList|HashSet|TreeSet|HashMap|TreeMap)<>\(\))|((ImmutableList|ImmutableMap|ImmutableBiMap|ImmutableSortedMap|ImmutableSet|ImmutableSortedSet|ImmutableTable)\.of\(\))" within="" contains="" />
<constraint name="BuilderAnnotation" regexp="lombok\.Builder" within="" contains="" />
<constraint name="Class" within="" contains="" />
</searchConfiguration>
<searchConfiguration name="Field in a non-@Builder class is annotated as @Builder.Default. It has no effect, thus can be removed." text="@$BuilderAnnotation$( ) class $Class$ { @$BuilderDefaultAnnotation$( ) @Modifier("Instance") $FieldType$ $Field$ = $Init$; }" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="BuilderAnnotation" regexp="lombok\.Builder" minCount="0" maxCount="0" within="" contains="" />
<constraint name="Class" within="" contains="" />
<constraint name="BuilderDefaultAnnotation" regexp="lombok\.Builder\.Default" within="" contains="" />
<constraint name="FieldType" maxCount="2147483647" within="" contains="" />
<constraint name="Field" maxCount="2147483647" target="true" within="" contains="" />
<constraint name="Init" minCount="0" within="" contains="" />
</searchConfiguration>
<searchConfiguration name="Static field in a @Builder class is annotated as @Builder.Default, which has no effect. It can be removed." text="@$BuilderAnnotation$( ) class $Class$ { @$BuilderDefaultAnnotation$( ) static $FieldType$ $Field$ = $Init$; }" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="BuilderAnnotation" regexp="lombok\.Builder" within="" contains="" />
<constraint name="Class" within="" contains="" />
<constraint name="BuilderDefaultAnnotation" regexp="lombok\.Builder\.Default" within="" contains="" />
<constraint name="FieldType" maxCount="2147483647" within="" contains="" />
<constraint name="Field" maxCount="2147483647" target="true" within="" contains="" />
<constraint name="Init" minCount="0" within="" contains="" />
<constraint name="__context__" within="" contains="" />
</searchConfiguration>
2018.12.03 - Lombok @Builder.Default field is not initialized
<searchConfiguration name="@Builder.Default field is not initialized. Either remove the annotation or initialize the field explicitly." text="@$BuilderAnnotation$( ) class $Class$ { @$BuilderDefaultAnnotation$( ) @$SingularAnnotation$( ) @Modifier("Instance") $FieldType$ $Field$ = $Init$; }" recursive="true" caseInsensitive="true" type="JAVA">
<constraint name="BuilderAnnotation" regexp="lombok\.Builder" within="" contains="" />
<constraint name="Class" within="" contains="" />
<constraint name="FieldType" maxCount="2147483647" within="" contains="" />
<constraint name="Field" maxCount="2147483647" target="true" within="" contains="" />
<constraint name="Init" minCount="0" maxCount="0" within="" contains="" />
<constraint name="BuilderDefaultAnnotation" regexp="lombok\.Builder\.Default" within="" contains="" />
<constraint name="__context__" within="" contains="" />
<constraint name="SingularAnnotation" regexp="lombok\.Singular" minCount="0" maxCount="0" within="" contains="" />
</searchConfiguration>
<searchConfiguration name="Slf4j Logger is defined explicitly. Use Lombok @Slf4j annotation instead." text="private static final $Logger$ $LOG$ = $LoggerFactory$.getLogger($Class$.class);" recursive="true" caseInsensitive="true" type="JAVA">
<constraint name="__context__" within="" contains="" />
<constraint name="Logger" regexp="org\.slf4j\.Logger" within="" contains="" />
<constraint name="LoggerFactory" regexp="org\.slf4j\.LoggerFactory" within="" contains="" />
<constraint name="LOG" target="true" within="" contains="" />
<constraint name="Class" within="" contains="" />
</searchConfiguration>
2018.11.26 - WebElement type fields in page object classes are not annotated with FindBy/FindBys/FindAll
<searchConfiguration name="WebElement/List<WebElement> type field is not annotated as FindBy, FindBys or FindAll" text="@$PageAnnotation$ class $Class$ { @$FindAnnotation$( ) @Modifier("Instance") $FieldType$ <$GenericArgument$> $Field$; }" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="PageAnnotation" regexp="picimako\.tutorial\.example\.annotation\.Page" within="" contains="" />
<constraint name="Class" within="" contains="" />
<constraint name="FindAnnotation" regexp="org\.openqa\.selenium\.support\.(FindBy|FindBys|FindAll)" minCount="0" maxCount="0" within="" contains="" />
<constraint name="FieldType" regexp="org\.openqa\.selenium\.WebElement|java\.util\.List" maxCount="2147483647" within="" contains="" />
<constraint name="Field" maxCount="2147483647" target="true" within="" contains="" />
<constraint name="GenericArgument" regexp="org\.openqa\.selenium\.WebElement" minCount="0" within="" contains="" />
</searchConfiguration>
2018.11.23. - Class containing FindBy/FindBys/FindAll annotated field(s) is not annotated with page object annotation
<searchConfiguration name="Class containing FindBy/FindBys/FindAll annotated field(s) is not annotated as Page." text="@$PageAnnotation$( ) class $Class$ { @$FindAnnotation$( ) @Modifier("Instance") $FieldType$ <$GenericArgument$> $Field$; }" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="PageAnnotation" regexp="picimako\.tutorial\.annotation\.Page" minCount="0" maxCount="0" within="" contains="" />
<constraint name="Class" target="true" within="" contains="" />
<constraint name="FindAnnotation" regexp="org\.openqa\.selenium\.support\.(FindBy|FindBys|FindAll)" within="" contains="" />
<constraint name="FieldType" regexp="org\.openqa\.selenium\.WebElement|java\.util\.List" within="" contains="" />
<constraint name="Field" within="" contains="" />
<constraint name="__context__" within="" contains="" />
<constraint name="GenericArgument" regexp="org\.openqa\.selenium\.WebElement" minCount="0" within="" contains="" />
</searchConfiguration>
<replaceConfiguration name="Default JSON comparison mode is LENIENT, no need to specify explicitly." text="$ASSERTION_FLOW$.matchesJson($MODEL$, org.skyscreamer.jsonassert.JSONCompareMode.LENIENT);" recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" useStaticImport="true" replacement="$ASSERTION_FLOW$.matchesJson($MODEL$);">
<constraint name="__context__" target="true" within="" contains="" />
<constraint name="ASSERTION_FLOW" within="" contains="" />
<constraint name="MODEL" within="" contains="" />
</replaceConfiguration>
2018.11.16. - "".equals() call can be replaced with String.isEmpty()
<replaceConfiguration name=""".equals() call can be replaced by String.isEmpty()" text=""".equals($STRING_ARGUMENT$)" recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" useStaticImport="true" replacement="$STRING_ARGUMENT$.isEmpty()">
<constraint name="STRING_ARGUMENT" regexp="^".*"$" nameOfExprType="java\.lang\.String" expressionTypes="java.lang.String" negateName="true" within="" contains="" />
<constraint name="__context__" within="" contains="" />
</replaceConfiguration>
<replaceConfiguration name="Guava com.google.common.base.Preconditions.checkNotNull is in use. Apply quick fix to replace it to java.util.Objects.requireNonNull." created="1521563590516" text="com.google.common.base.Preconditions.$CHECK_METHOD$($ARGUMENTS$)"
recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" useStaticImport="true" replacement="java.util.Objects.requireNonNull($ARGUMENTS$)">
<constraint name="__context__" within="" contains="" />
<constraint name="ARGUMENTS" within="" contains="" />
<constraint name="CHECK_METHOD" regexp="checkNotNull" within="" contains="" />
</replaceConfiguration>
2018.11.09 - Annotation is used with default attribute value
<replaceConfiguration name="Retry annotation is used with default times value. Apply quick fix to remove the attribute." text="@picimako.tutorial.example.annotation.Retry(times = 1)" recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" useStaticImport="true" replacement="@picimako.tutorial.example.annotation.Retry">
<constraint name="__context__" target="true" within="" contains="" />
</replaceConfiguration>
2018.11.05. - Annotation with a certain attribute value is invalid
Retry annotation with 0 retry counts is invalid. Apply quick fix to remove the annotation:
<replaceConfiguration name="Retry annotation with 0 retry counts is invalid. Apply quick fix to remove the annotation." text="@picimako.tutorial.example.annotation.Retry(times = 0)"
recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" useStaticImport="true" replacement="" />
Retry annotation with 0 retry counts is invalid. Apply quick fix to remove the times attribute]():
<replaceConfiguration name="Retry annotation with 0 retry counts is invalid. Apply quick fix to remove the times attribute." text="@picimako.tutorial.example.annotation.Retry(times = 0)"
recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" useStaticImport="true" replacement="@picimako.tutorial.example.annotation.Retry" />
<searchConfiguration name="There is no actual assertion called from AssertJ SoftAssertions." text="$INSTANCE$.$ASSERTION_METHOD$($PARAMETER$);" recursive="false"
caseInsensitive="true" type="JAVA">
<constraint name="ASSERTION_METHOD" regexp="assertThat|assertThatCode|assertThatThrownBy" within="" contains=""/>
<constraint name="PARAMETER" within="" contains=""/>
<constraint name="INSTANCE" nameOfExprType="org\.assertj\.core\.api\.SoftAssertions" within="" contains=""/>
</searchConfiguration>
2018.10.29 - There is no actual assertion called from AssertJ
<searchConfiguration name="There is no actual assertion called from AssertJ." text="org.assertj.core.api.Assertions.$ASSERTION_METHOD$($PARAMETER$);" recursive="true" caseInsensitive="true" type="JAVA">
<constraint name="ASSERTION_METHOD" regexp="assertThat(|ThrownBy|Code|ExceptionOfType|NullPointerException|IllegalArgumentException|IOException|IllegalStateException)" within="" contains="" />
<constraint name="PARAMETER" within="" contains="" />
<constraint name="__context__" within="" contains="" />
</searchConfiguration>
2018.10.26. - BDD step definition method has more than X arguments
<searchConfiguration name="Step definition method has more than 3 parameters. Consider reorganizing or splitting steps." text="@$Annotation$( ) $MethodType$ $Method$($ParameterType$ $Parameter$);" recursive="true" caseInsensitive="true" type="JAVA">
<constraint name="Annotation" regexp="cucumber\.api\.java\.en\.(Given|When|Then)" within="" contains="" />
<constraint name="MethodType" within="" contains="" />
<constraint name="Method" target="true" within="" contains="" />
<constraint name="ParameterType" minCount="4" maxCount="2147483647" within="" contains="" />
<constraint name="Parameter" minCount="4" maxCount="2147483647" within="" contains="" />
<constraint name="__context__" within="" contains="" />
</searchConfiguration>
2018.10.22. - A static method is not used with static import
<searchConfiguration name="Mockito method is not used with static import." text="$Instance$.$MethodCall$($Parameter$)" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="__context__" within="" contains=""/>
<constraint name="Instance" regexp="org\.mockito\.Mockito" within="" contains=""/>
<constraint name="MethodCall" target="true" within="" contains=""/>
<constraint name="Parameter" minCount="0" maxCount="2147483647" within="" contains=""/>
</searchConfiguration>
<searchConfiguration name="Class, having name ending with Feature, does not extend a certain class" text="class $Class$ extends $Parent$ {}" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="Class" script=""!__context__.interface && !__context__.enum"" regexp=".*Feature$" target="true" within="" contains="" />
<constraint name="Parent" regexp="^picimako\.tutorial\.example\.BaseFeature$" minCount="0" maxCount="0" within="" contains="" />
<constraint name="__context__" within="" contains="" />
</searchConfiguration>
<searchConfiguration name="Class, having name ending with Feature, is not annotated as Feature." text="@$Annotation$( ) class $Class$ {}" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="Annotation" regexp="picimako\.tutorial\.example\.annotation\.Feature" minCount="0" maxCount="0" within="" contains="" />
<constraint name="Class" script=""!__context__.interface && !__context__.enum"" regexp=".*Feature$" target="true" within="" contains="" />
</searchConfiguration>
2018.10.15. - Annotated class name doesn't end with a keyword
<searchConfiguration name="Annotated class name doesn't end with a keyword" text="@$Annotation$( ) class $Class$ {}" recursive="true" caseInsensitive="true" type="JAVA">
<constraint name="__context__" within="" contains="" />
<constraint name="Annotation" regexp="picimako\.tutorial\.example\.annotation\.Feature" within="" contains="" />
<constraint name="Class" regexp=".*(?<!Feature)$" target="true" within="" contains="" />
</searchConfiguration>
2018.10.05. - Class name doesn't end with a certain keyword
<searchConfiguration name="Class name doesn't end with the Feature keyword" text="class $Class$ {}" recursive="false" caseInsensitive="true" type="JAVA">
<constraint name="Class" script=""!__context__.interface && !__context__.enum"" regexp=".*(?<!Feature)$" target="true" within="" contains="" />
</searchConfiguration>