diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml
index 709645aa6..d0a684182 100644
--- a/resources/META-INF/plugin.xml
+++ b/resources/META-INF/plugin.xml
@@ -153,64 +153,72 @@
+
+
diff --git a/resources/inspectionDescriptions/InvalidDiTypeInspection.html b/resources/inspectionDescriptions/InvalidDiTypeInspection.html
new file mode 100644
index 000000000..ff01cbdcb
--- /dev/null
+++ b/resources/inspectionDescriptions/InvalidDiTypeInspection.html
@@ -0,0 +1,22 @@
+
+
+
+
+ Validates if all types inside the <type/> tag of di.xml files contains valid classes,
+ interfaces, factories, proxies or virtual type names.
+
+This inspection checks name attribute of the <type/> tag and all arguments recursively which has xsi:type attribute value as object.
+This inspection supports next types:
+
+ - PHP classes
+ - PHP interfaces
+ - PHP classes or interfaces with added Factory or \Proxy suffixes
+ - Magento 2 Virtual Types names
+
+
+
diff --git a/resources/magento2/inspection.properties b/resources/magento2/inspection.properties
index d12e724f1..8ed815dc5 100644
--- a/resources/magento2/inspection.properties
+++ b/resources/magento2/inspection.properties
@@ -1,3 +1,13 @@
+inspection.group.name=Magento 2
+inspection.displayName.PluginInspection=Inspection for the Plugin declaration
+inspection.displayName.ModuleDeclarationInRegistrationPhpInspection=Inspection for the Module declaration in the `registration.php` file
+inspection.displayName.ObserverDeclarationInspection=Duplicated Observer Usage in events XML
+inspection.displayName.PluginDeclarationInspection=Duplicated Plugin Usage in di XML
+inspection.displayName.CacheableFalseInDefaultLayoutInspection=Inspection for disabled cache site-wide
+inspection.displayName.ModuleDeclarationInModuleXmlInspection=Inspection for the Module declaration in the `etc/module.xml` file
+inspection.displayName.AclResourceXmlInspection=Inspection for the Title XML required attribute in the `etc/acl.xml` file
+inspection.displayName.WebApiServiceInspection=Inspection for the Web API XML service declaration
+inspection.displayName.InvalidDiTypeInspection=Invalid type configuration in the `etc/di.xml` file
inspection.plugin.duplicateInSameFile=The plugin name already used in this file. For more details see Inspection Description.
inspection.plugin.duplicateInOtherPlaces=The plugin name "{0}" for targeted "{1}" class is already used in the module "{2}" ({3} scope). For more details see Inspection Description.
inspection.plugin.disabledPluginDoesNotExist=This plugin does not exist to be disabled.
diff --git a/src/com/magento/idea/magento2plugin/inspections/validator/InspectionValidator.java b/src/com/magento/idea/magento2plugin/inspections/validator/InspectionValidator.java
new file mode 100644
index 000000000..543ec88d8
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/inspections/validator/InspectionValidator.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.inspections.validator;
+
+/**
+ * All Inspections validators should implement this validator.
+ */
+public interface InspectionValidator {
+
+ /**
+ * Validate if provided value acceptable by concrete validator implementation.
+ *
+ * @param value String
+ *
+ * @return boolean
+ */
+ boolean validate(final String value);
+}
diff --git a/src/com/magento/idea/magento2plugin/inspections/validator/NotEmptyValidator.java b/src/com/magento/idea/magento2plugin/inspections/validator/NotEmptyValidator.java
new file mode 100644
index 000000000..c101772fd
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/inspections/validator/NotEmptyValidator.java
@@ -0,0 +1,14 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.inspections.validator;
+
+public class NotEmptyValidator implements InspectionValidator {
+
+ @Override
+ public boolean validate(final String value) {
+ return value != null && !value.isEmpty();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/inspections/validator/PhpClassExistenceValidator.java b/src/com/magento/idea/magento2plugin/inspections/validator/PhpClassExistenceValidator.java
new file mode 100644
index 000000000..b613c0f87
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/inspections/validator/PhpClassExistenceValidator.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.inspections.validator;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.php.PhpIndex;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+import java.util.Collection;
+import org.jetbrains.annotations.NotNull;
+
+public class PhpClassExistenceValidator implements InspectionValidator {
+
+ private final PhpIndex phpIndex;
+
+ public PhpClassExistenceValidator(final @NotNull Project project) {
+ phpIndex = PhpIndex.getInstance(project);
+ }
+
+ @Override
+ public boolean validate(final String value) {
+ if (value == null) {
+ return false;
+ }
+ final @NotNull Collection classes = phpIndex.getClassesByFQN(value);
+ final @NotNull Collection interfaces = phpIndex.getInterfacesByFQN(value);
+
+ return !classes.isEmpty() || !interfaces.isEmpty();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/inspections/validator/VirtualTypeExistenceValidator.java b/src/com/magento/idea/magento2plugin/inspections/validator/VirtualTypeExistenceValidator.java
new file mode 100644
index 000000000..3edfbbfd7
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/inspections/validator/VirtualTypeExistenceValidator.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.inspections.validator;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.indexing.FileBasedIndex;
+import com.magento.idea.magento2plugin.stubs.indexes.VirtualTypeIndex;
+import java.util.Collection;
+import org.jetbrains.annotations.NotNull;
+
+public class VirtualTypeExistenceValidator implements InspectionValidator {
+
+ private final Project project;
+
+ public VirtualTypeExistenceValidator(final @NotNull Project project) {
+ this.project = project;
+ }
+
+ @Override
+ public boolean validate(final String value) {
+ if (value == null) {
+ return false;
+ }
+ final @NotNull Collection virtualTypes = FileBasedIndex.getInstance().getValues(
+ VirtualTypeIndex.KEY,
+ value,
+ GlobalSearchScope.allScope(project)
+ );
+
+ return !virtualTypes.isEmpty();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/inspections/xml/InvalidDependencyInjectionTypeInspection.java b/src/com/magento/idea/magento2plugin/inspections/xml/InvalidDependencyInjectionTypeInspection.java
new file mode 100644
index 000000000..bf96bf75d
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/inspections/xml/InvalidDependencyInjectionTypeInspection.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.inspections.xml;
+
+import com.intellij.codeInspection.ProblemHighlightType;
+import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInspection.XmlSuppressableInspectionTool;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.XmlElementVisitor;
+import com.intellij.psi.xml.XmlAttribute;
+import com.intellij.psi.xml.XmlTag;
+import com.magento.idea.magento2plugin.bundles.InspectionBundle;
+import com.magento.idea.magento2plugin.inspections.validator.InspectionValidator;
+import com.magento.idea.magento2plugin.inspections.validator.NotEmptyValidator;
+import com.magento.idea.magento2plugin.inspections.validator.PhpClassExistenceValidator;
+import com.magento.idea.magento2plugin.inspections.validator.VirtualTypeExistenceValidator;
+import com.magento.idea.magento2plugin.magento.files.ModuleDiXml;
+import com.magento.idea.magento2plugin.util.xml.XmlPsiTreeUtil;
+import java.util.List;
+import org.jetbrains.annotations.NotNull;
+
+@SuppressWarnings({"PMD.ExcessiveMethodLength", "PMD.NPathComplexity"})
+public class InvalidDependencyInjectionTypeInspection extends XmlSuppressableInspectionTool {
+
+ @Override
+ public @NotNull PsiElementVisitor buildVisitor(
+ final @NotNull ProblemsHolder problemsHolder,
+ final boolean isOnTheFly
+ ) {
+ return new XmlElementVisitor() {
+
+ // Used to show messages for inspection scope.
+ private final InspectionBundle inspectionBundle = new InspectionBundle();
+ // Inspection validators
+ private final InspectionValidator phpClassExistenceValidator =
+ new PhpClassExistenceValidator(problemsHolder.getProject());
+ private final InspectionValidator virtualTypeExistenceValidator =
+ new VirtualTypeExistenceValidator(problemsHolder.getProject());
+ private final InspectionValidator notEmptyValidator = new NotEmptyValidator();
+
+ @Override
+ public void visitXmlTag(final @NotNull XmlTag xmlTag) {
+ final PsiFile file = xmlTag.getContainingFile();
+
+ if (!file.getName().equals(ModuleDiXml.FILE_NAME)
+ || !xmlTag.getName().equals(ModuleDiXml.TYPE_TAG)) {
+ return;
+ }
+ final XmlAttribute nameAttribute = xmlTag.getAttribute(ModuleDiXml.NAME_ATTR);
+
+ if (nameAttribute == null
+ || nameAttribute.getValue() == null
+ || nameAttribute.getValueElement() == null) {
+ return;
+ }
+
+ //Check whether the name attribute is not empty
+ if (!notEmptyValidator.validate(nameAttribute.getValue())) {
+ reportCouldNotBeEmpty(
+ nameAttribute.getValueElement(),
+ nameAttribute.getName()
+ );
+ }
+
+ //Check whether the class exists
+ if (!phpClassExistenceValidator.validate(nameAttribute.getValue())) {
+ reportClassDoesNotExists(
+ nameAttribute.getValueElement(),
+ nameAttribute.getValue()
+ );
+ }
+ final XmlTag argumentsTag = xmlTag.findFirstSubTag(ModuleDiXml.ARGUMENTS_TAG);
+
+ // Break visiting if there are no arguments
+ if (argumentsTag == null) {
+ return;
+ }
+
+ final List argumentsTags = XmlPsiTreeUtil.findSubTagsOfParent(
+ argumentsTag,
+ ModuleDiXml.ARGUMENT_TAG
+ );
+
+ for (final XmlTag argumentTag : argumentsTags) {
+ checkObjectArgumentsRecursively(argumentTag);
+ }
+ }
+
+ /**
+ * Recursively check all xsi-type object attributes.
+ *
+ * @param tag XmlTag
+ */
+ private void checkObjectArgumentsRecursively(final @NotNull XmlTag tag) {
+ final XmlAttribute xsiTypeAttr = tag.getAttribute(ModuleDiXml.XSI_TYPE_ATTR);
+
+ if (xsiTypeAttr == null
+ || xsiTypeAttr.getValueElement() == null
+ || xsiTypeAttr.getValue() == null) {
+ return;
+ }
+ final String xsiTypeValue = xsiTypeAttr.getValue();
+
+ if (xsiTypeValue.equals(ModuleDiXml.XSI_TYPE_ARRAY)) {
+ final List itemsTags = XmlPsiTreeUtil.findSubTagsOfParent(
+ tag,
+ ModuleDiXml.ITEM_TAG
+ );
+ if (itemsTags.isEmpty()) {
+ return;
+ }
+
+ for (final XmlTag itemTag : itemsTags) {
+ checkObjectArgumentsRecursively(itemTag);
+ }
+ } else if (xsiTypeValue.equals(ModuleDiXml.XSI_TYPE_OBJECT)) {
+ final String tagValue = tag.getValue().getText();
+
+ if (tagValue.isEmpty()) {
+ return;
+ }
+ final String cleanType = tagValue
+ .replace("Factory", "")
+ .replace("\\Proxy", "");
+
+ if (!phpClassExistenceValidator.validate(cleanType)
+ && !virtualTypeExistenceValidator.validate(tagValue)) {
+ reportClassDoesNotExists(tag, tagValue);
+ }
+ }
+ }
+
+ /**
+ * Report Attribute Value could not be empty.
+ *
+ * @param psiElement PsiElement
+ * @param messageParams Object...
+ */
+ private void reportCouldNotBeEmpty(
+ final @NotNull PsiElement psiElement,
+ final Object... messageParams
+ ) {
+ problemsHolder.registerProblem(
+ psiElement,
+ inspectionBundle.message(
+ "inspection.error.idAttributeCanNotBeEmpty",
+ messageParams
+ ),
+ ProblemHighlightType.ERROR
+ );
+ }
+
+ /**
+ * Report class does not exists.
+ *
+ * @param psiElement PsiElement
+ * @param messageParams Object...
+ */
+ private void reportClassDoesNotExists(
+ final @NotNull PsiElement psiElement,
+ final Object... messageParams
+ ) {
+ problemsHolder.registerProblem(
+ psiElement,
+ inspectionBundle.message(
+ "inspection.warning.class.does.not.exist",
+ messageParams
+ ),
+ ProblemHighlightType.WARNING
+ );
+ }
+ };
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/inspections/xml/WebApiServiceInspection.java b/src/com/magento/idea/magento2plugin/inspections/xml/WebApiServiceInspection.java
index 01cbeaadf..1913ffa18 100644
--- a/src/com/magento/idea/magento2plugin/inspections/xml/WebApiServiceInspection.java
+++ b/src/com/magento/idea/magento2plugin/inspections/xml/WebApiServiceInspection.java
@@ -17,6 +17,9 @@
import com.jetbrains.php.lang.psi.elements.Method;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.magento.idea.magento2plugin.bundles.InspectionBundle;
+import com.magento.idea.magento2plugin.inspections.validator.InspectionValidator;
+import com.magento.idea.magento2plugin.inspections.validator.NotEmptyValidator;
+import com.magento.idea.magento2plugin.inspections.validator.PhpClassExistenceValidator;
import com.magento.idea.magento2plugin.inspections.xml.fix.MethodNotPublicAccessQuickFix;
import com.magento.idea.magento2plugin.magento.files.ModuleWebApiXmlFile;
import java.util.Collection;
@@ -33,7 +36,12 @@ public PsiElementVisitor buildVisitor(
final boolean isOnTheFly
) {
return new XmlElementVisitor() {
+
private final InspectionBundle inspectionBundle = new InspectionBundle();
+ // Inspection validators
+ private final InspectionValidator notEmptyValidator = new NotEmptyValidator();
+ private final InspectionValidator phpClassExistenceValidator =
+ new PhpClassExistenceValidator(problemsHolder.getProject());
@Override
public void visitXmlTag(final XmlTag xmlTag) {
@@ -55,7 +63,8 @@ public void visitXmlTag(final XmlTag xmlTag) {
return;
}
final String classFqn = classAttribute.getValue();
- if (classFqn == null || classFqn.isEmpty()) {
+
+ if (!notEmptyValidator.validate(classFqn)) {
problemsHolder.registerProblem(
classAttribute,
inspectionBundle.message(
@@ -68,14 +77,7 @@ public void visitXmlTag(final XmlTag xmlTag) {
return;
}
- //Check whether the class exists
- final PhpIndex phpIndex = PhpIndex.getInstance(
- problemsHolder.getProject()
- );
- @NotNull final Collection classes = phpIndex.getClassesByFQN(classFqn);
- @NotNull final Collection interfaces = phpIndex
- .getInterfacesByFQN(classFqn);
- if (classes.isEmpty() && interfaces.isEmpty()) {
+ if (!phpClassExistenceValidator.validate(classFqn)) {
problemsHolder.registerProblem(
classAttribute,
inspectionBundle.message(
@@ -95,7 +97,8 @@ public void visitXmlTag(final XmlTag xmlTag) {
return;
}
final String methodName = methodAttribute.getValue();
- if (methodName == null || methodName.isEmpty()) {
+
+ if (!notEmptyValidator.validate(methodName)) {
problemsHolder.registerProblem(
classAttribute,
inspectionBundle.message(
@@ -109,10 +112,16 @@ public void visitXmlTag(final XmlTag xmlTag) {
}
//Check whether method exists
+ final PhpIndex phpIndex = PhpIndex.getInstance(problemsHolder.getProject());
+ final @NotNull Collection classes = phpIndex.getClassesByFQN(classFqn);
+ final @NotNull Collection interfaces = phpIndex
+ .getInterfacesByFQN(classFqn);
+
Method targetMethod = findTargetMethod(classes, methodName);
if (targetMethod == null) {
targetMethod = findTargetMethod(interfaces, methodName);
}
+
if (targetMethod == null && methodAttribute.getValueElement() != null) {
problemsHolder.registerProblem(
methodAttribute.getValueElement(),
@@ -127,7 +136,9 @@ public void visitXmlTag(final XmlTag xmlTag) {
}
//API method should have public access
- if (targetMethod.getAccess() != null && !targetMethod.getAccess().isPublic()) {
+ if (targetMethod != null
+ && targetMethod.getAccess() != null
+ && !targetMethod.getAccess().isPublic()) {
problemsHolder.registerProblem(
methodAttribute,
inspectionBundle.message(
@@ -140,8 +151,7 @@ public void visitXmlTag(final XmlTag xmlTag) {
}
}
- @Nullable
- private Method findTargetMethod(
+ private @Nullable Method findTargetMethod(
final Collection classes,
final String methodName
) {
diff --git a/src/com/magento/idea/magento2plugin/magento/files/ModuleDiXml.java b/src/com/magento/idea/magento2plugin/magento/files/ModuleDiXml.java
index 36b115643..7db65c0cd 100644
--- a/src/com/magento/idea/magento2plugin/magento/files/ModuleDiXml.java
+++ b/src/com/magento/idea/magento2plugin/magento/files/ModuleDiXml.java
@@ -54,6 +54,7 @@ public class ModuleDiXml implements ModuleFileInterface {
public static String XSI_TYPE_ATTR = "xsi:type";
// attribute values
+ public static String XSI_TYPE_OBJECT = "object";
public static String XSI_TYPE_STRING = "string";
public static String XSI_TYPE_ARRAY = "array";
public static String COLLECTIONS_ATTR_VALUE = "collections";
diff --git a/testData/inspections/xml/TypeConfigurationTagTypesInspection/argumentFactoryTypeExists/di.xml b/testData/inspections/xml/TypeConfigurationTagTypesInspection/argumentFactoryTypeExists/di.xml
new file mode 100644
index 000000000..c18bf23e9
--- /dev/null
+++ b/testData/inspections/xml/TypeConfigurationTagTypesInspection/argumentFactoryTypeExists/di.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Magento\Catalog\Api\ProductRepositoryInterfaceFactory
+
+
+
diff --git a/testData/inspections/xml/TypeConfigurationTagTypesInspection/nameAttributeValueTypeDoesNotExist/di.xml b/testData/inspections/xml/TypeConfigurationTagTypesInspection/nameAttributeValueTypeDoesNotExist/di.xml
new file mode 100644
index 000000000..8e1497751
--- /dev/null
+++ b/testData/inspections/xml/TypeConfigurationTagTypesInspection/nameAttributeValueTypeDoesNotExist/di.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/testData/inspections/xml/TypeConfigurationTagTypesInspection/nameAttributeValueTypeExists/di.xml b/testData/inspections/xml/TypeConfigurationTagTypesInspection/nameAttributeValueTypeExists/di.xml
new file mode 100644
index 000000000..0e764caa1
--- /dev/null
+++ b/testData/inspections/xml/TypeConfigurationTagTypesInspection/nameAttributeValueTypeExists/di.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentProxyTypeDoesNotExist/di.xml b/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentProxyTypeDoesNotExist/di.xml
new file mode 100644
index 000000000..b237d29d3
--- /dev/null
+++ b/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentProxyTypeDoesNotExist/di.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ -
+
- Not\Existent\Class\Proxy
+
+
+
+
+
diff --git a/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentProxyTypeExists/di.xml b/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentProxyTypeExists/di.xml
new file mode 100644
index 000000000..e4c767109
--- /dev/null
+++ b/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentProxyTypeExists/di.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ -
+
- Magento\Catalog\Api\ProductRepositoryInterface\Proxy
+
+
+
+
+
diff --git a/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentVirtualTypeDoesNotExist/di.xml b/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentVirtualTypeDoesNotExist/di.xml
new file mode 100644
index 000000000..2d8188236
--- /dev/null
+++ b/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentVirtualTypeDoesNotExist/di.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ -
+
- NotExistentVirtualType
+
+
+
+
+
diff --git a/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentVirtualTypeExists/di.xml b/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentVirtualTypeExists/di.xml
new file mode 100644
index 000000000..f790b54f7
--- /dev/null
+++ b/testData/inspections/xml/TypeConfigurationTagTypesInspection/recursivelyArgumentVirtualTypeExists/di.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ -
+
- VirtualProductRepository
+
+
+
+
+
diff --git a/testData/project/magento2/app/code/Foo/Bar2/composer.json b/testData/project/magento2/app/code/Foo/Bar2/composer.json
new file mode 100755
index 000000000..d53cc631e
--- /dev/null
+++ b/testData/project/magento2/app/code/Foo/Bar2/composer.json
@@ -0,0 +1,17 @@
+{
+ "name": "foo/bar2",
+ "description": "N/A",
+ "type": "magento2-module",
+ "version": "1.0.0",
+ "require": {
+ "magento/framework": "*"
+ },
+ "autoload": {
+ "files": [
+ "registration.php"
+ ],
+ "psr-4": {
+ "Foo\\Bar2\\": ""
+ }
+ }
+}
diff --git a/testData/project/magento2/app/code/Foo/Bar2/etc/di.xml b/testData/project/magento2/app/code/Foo/Bar2/etc/di.xml
new file mode 100644
index 000000000..56852742c
--- /dev/null
+++ b/testData/project/magento2/app/code/Foo/Bar2/etc/di.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/testData/project/magento2/app/code/Foo/Bar2/etc/module.xml b/testData/project/magento2/app/code/Foo/Bar2/etc/module.xml
new file mode 100755
index 000000000..103177a10
--- /dev/null
+++ b/testData/project/magento2/app/code/Foo/Bar2/etc/module.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/testData/project/magento2/app/code/Foo/Bar2/registration.php b/testData/project/magento2/app/code/Foo/Bar2/registration.php
new file mode 100755
index 000000000..1ca433f95
--- /dev/null
+++ b/testData/project/magento2/app/code/Foo/Bar2/registration.php
@@ -0,0 +1,6 @@
+.
+ */
+ public void testNameAttributeValueTypeDoesNotExist() {
+ configureFixture();
+
+ final String errorMessage = inspectionBundle.message(
+ CLASS_DOES_NOT_EXIST,
+ NOT_EXISTENT_CLASS
+ );
+
+ assertHasHighlighting(errorMessage);
+ }
+
+ /**
+ * Test type exists: .
+ */
+ public void testNameAttributeValueTypeExists() {
+ configureFixture();
+
+ final String errorMessage = inspectionBundle.message(
+ CLASS_DOES_NOT_EXIST,
+ "Magento\\Catalog\\Api\\ProductRepositoryInterface"
+ );
+
+ assertHasNoHighlighting(errorMessage);
+ }
+
+ /**
+ * Test argument factory type exists: TestingTypeFactory.
+ */
+ public void testArgumentFactoryTypeExists() {
+ configureFixture();
+
+ final String errorMessage = inspectionBundle.message(
+ CLASS_DOES_NOT_EXIST,
+ "Magento\\Catalog\\Api\\ProductRepositoryInterfaceFactory"
+ );
+
+ assertHasNoHighlighting(errorMessage);
+ }
+
+ /**
+ * Test proxy type doesn't exist highlighting:
+ * - TestType\Proxy
.
+ */
+ public void testRecursivelyArgumentProxyTypeDoesNotExist() {
+ configureFixture();
+
+ final String errorMessage = inspectionBundle.message(
+ CLASS_DOES_NOT_EXIST,
+ NOT_EXISTENT_CLASS.concat("\\Proxy")
+ );
+
+ assertHasHighlighting(errorMessage);
+ }
+
+ /**
+ * Test proxy type exists.
+ * - TestType\Proxy
+ */
+ public void testRecursivelyArgumentProxyTypeExists() {
+ configureFixture();
+
+ final String errorMessage = inspectionBundle.message(
+ CLASS_DOES_NOT_EXIST,
+ "Magento\\Catalog\\Api\\ProductRepositoryInterfaceFactory\\Proxy"
+ );
+
+ assertHasNoHighlighting(errorMessage);
+ }
+
+ /**
+ * Test proxy type doesn't exist highlighting:
+ * - TestType\Proxy
.
+ */
+ public void testRecursivelyArgumentVirtualTypeDoesNotExist() {
+ configureFixture();
+
+ final String errorMessage = inspectionBundle.message(
+ CLASS_DOES_NOT_EXIST,
+ NOT_EXISTENT_VIRTUAL_TYPE
+ );
+
+ assertHasHighlighting(errorMessage);
+ }
+
+ /**
+ * Test virtual type exists.
+ * - TestVirtualType
+ */
+ public void testRecursivelyArgumentVirtualTypeExists() {
+ configureFixture();
+
+ final String errorMessage = inspectionBundle.message(
+ CLASS_DOES_NOT_EXIST,
+ EXISTENT_VIRTUAL_TYPE
+ );
+
+ assertHasNoHighlighting(errorMessage);
+ }
+
+ private void configureFixture() {
+ myFixture.configureByFile(getFixturePath(ModuleDiXml.FILE_NAME));
+ }
+}