Skip to content

Commit

Permalink
fix(line-marker): False positive with method calls (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
olivernybroe authored Jul 20, 2020
1 parent 930ae96 commit b4a7aa9
Show file tree
Hide file tree
Showing 23 changed files with 177 additions and 67 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Fixed
- Plugin require restart as PhpTestFrameworkType does not support dynamic plugins
- Line markers reported false positives with method calls([#31](https://github.com/pestphp/pest-intellij/pull/31))

## [v0.1.1]
### Added
Expand Down
11 changes: 7 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ plugins {
// gradle-intellij-plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin
id("org.jetbrains.intellij") version "0.4.21"
// gradle-changelog-plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin
id("org.jetbrains.changelog") version "0.3.2"
id("org.jetbrains.changelog") version "0.4.0"
// detekt linter - read more: https://detekt.github.io/detekt/kotlindsl.html
id("io.gitlab.arturbosch.detekt") version "1.10.0-RC1"
id("io.gitlab.arturbosch.detekt") version "1.10.0"
// ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle
id("org.jlleitschuh.gradle.ktlint") version "9.2.1"
}

// Import variables from gradle.properties file
Expand All @@ -38,7 +40,7 @@ repositories {
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.10.0-RC1")
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.10.0")
}

// Configure gradle-intellij-plugin plugin.
Expand All @@ -56,6 +58,7 @@ intellij {
// Read more: https://detekt.github.io/detekt/kotlindsl.html
detekt {
config = files("./detekt-config.yml")
buildUponDefaultConfig = true

reports {
html.enabled = false
Expand Down Expand Up @@ -107,4 +110,4 @@ tasks {
token(System.getenv("PUBLISH_TOKEN"))
channels(System.getenv("PUBLISH_CHANNEL"))
}
}
}
5 changes: 4 additions & 1 deletion detekt-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@

formatting:
Indentation:
active: true
active: true
style:
ReturnCount:
max: 10
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

pluginGroup = com.pestphp
pluginName = Pest
pluginVersion = 0.2.1-alpha.2
pluginVersion = 0.2.1-alpha.3
pluginSinceBuild = 201
pluginUntilBuild = null

platformType = IU
platformVersion = LATEST-EAP-SNAPSHOT
platformVersion = 2020.1.2
platformDownloadSources = true
platformPlugins = com.jetbrains.php:202.6250.23
platformPlugins = com.jetbrains.php:201.7846.90

2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
rootProject.name = "pest-intellij"
rootProject.name = "pest-intellij"
2 changes: 1 addition & 1 deletion src/main/kotlin/com/pestphp/pest/PestIconProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ class PestIconProvider : IconProvider() {

return null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@ import com.intellij.psi.PsiElement
import com.jetbrains.php.lang.lexer.PhpTokenTypes
import com.jetbrains.php.lang.psi.PhpPsiUtil
import com.jetbrains.php.lang.psi.elements.FunctionReference
import com.jetbrains.php.lang.psi.elements.impl.FunctionReferenceImpl

class PestTestRunLineMarkerProvider : RunLineMarkerContributor() {
override fun getInfo(leaf: PsiElement): Info? {
if (!PhpPsiUtil.isOfType(leaf, PhpTokenTypes.IDENTIFIER)) {
return null
}

// return RunLineMarkerContributor.withExecutorActions(getTestStateIcon(getLocationHint(testName), leaf.getProject(), false));
return when {
leaf.parent !is FunctionReference -> null
leaf.parent !is FunctionReferenceImpl -> null
(leaf.parent as FunctionReference).isPestTestFunction() -> withExecutorActions(PestIcons.RUN_SINGLE_TEST)
else -> null
}

}
}
}
17 changes: 7 additions & 10 deletions src/main/kotlin/com/pestphp/pest/PestUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import com.jetbrains.php.phpunit.PhpUnitUtil
import com.jetbrains.php.testFramework.PhpTestFrameworkConfiguration
import com.jetbrains.php.testFramework.PhpTestFrameworkSettingsManager


fun PsiElement?.isPestTestFunction(): Boolean {
return when (this) {
null -> false
Expand All @@ -33,7 +32,6 @@ fun MethodReference.isPestTestFunction(): Boolean {
return reference != null && reference.isPestTestFunction()
}


fun FunctionReference.getPestTestName(): String? {
return when (val parameter = this.getParameter(0)) {
is StringLiteralExpression -> parameter.contents
Expand All @@ -49,13 +47,12 @@ fun PsiElement?.getPestTestName(): String? {
}
}


fun PsiFile.isPestTestFile(): Boolean {
return when (this) {
is PhpFile -> {
PsiTreeUtil.findChildrenOfType(this, FunctionReference::class.java)
.asSequence()
.any(FunctionReference::isPestTestFunction)
.asSequence()
.any(FunctionReference::isPestTestFunction)
}
else -> false
}
Expand All @@ -67,8 +64,8 @@ fun PsiFile.isPestConfigurationFile(): Boolean {

fun Project.isPestEnabled(): Boolean {
return PhpTestFrameworkSettingsManager
.getInstance(this)
.getConfigurations(PestFrameworkType.getInstance())
.stream()
.anyMatch { config: PhpTestFrameworkConfiguration -> StringUtil.isNotEmpty(config.executablePath) }
}
.getInstance(this)
.getConfigurations(PestFrameworkType.getInstance())
.stream()
.anyMatch { config: PhpTestFrameworkConfiguration -> StringUtil.isNotEmpty(config.executablePath) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package com.pestphp.pest.configuration

import com.jetbrains.php.testFramework.run.PhpTestDebugRunner

class PestDebugRunner private constructor() : PhpTestDebugRunner<PestRunConfiguration>(PestRunConfiguration::class.java) {
class PestDebugRunner
private constructor() : PhpTestDebugRunner<PestRunConfiguration>(PestRunConfiguration::class.java) {
override fun getRunnerId(): String {
return "PestDebugRunner"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,51 @@ class PestRunConfigurationHandler : PhpTestRunConfigurationHandler {
}

override fun prepareCommand(project: Project, commandSettings: PhpCommandSettings, exe: String, version: String?) {
// String scriptFile = PhpExecutionUtil.loadHelperScriptAndGetText(project, "behat.php", commandSettings, PestRunConfigurationHandler.class);
commandSettings.setScript(exe, false)
commandSettings.addArgument("--teamcity")
commandSettings.addEnv("IDE_PEST_EXE", exe)


if (!version.isNullOrEmpty()) {
commandSettings.addEnv("IDE_PEST_VERSION", version)
}
}

@Throws(ExecutionException::class)
override fun runType(project: Project, phpCommandSettings: PhpCommandSettings, type: String, workingDirectory: String) {
override fun runType(
project: Project,
phpCommandSettings: PhpCommandSettings,
type: String,
workingDirectory: String
) {
throw ExecutionException("Can not run pest with type.")
}

override fun runDirectory(project: Project, phpCommandSettings: PhpCommandSettings, directory: String, workingDirectory: String) {
override fun runDirectory(
project: Project,
phpCommandSettings: PhpCommandSettings,
directory: String,
workingDirectory: String
) {
phpCommandSettings.addPathArgument(directory)
}

override fun runFile(project: Project, phpCommandSettings: PhpCommandSettings, file: String, workingDirectory: String) {
override fun runFile(
project: Project,
phpCommandSettings: PhpCommandSettings,
file: String,
workingDirectory: String
) {
phpCommandSettings.addPathArgument(file)
}

override fun runMethod(project: Project, phpCommandSettings: PhpCommandSettings, file: String, methodName: String, workingDirectory: String) {
override fun runMethod(
project: Project,
phpCommandSettings: PhpCommandSettings,
file: String,
methodName: String,
workingDirectory: String
) {
phpCommandSettings.addPathArgument(file)
phpCommandSettings.addArgument(String.format("--filter=/%s$/", methodName.replace(" ", "\\s")))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ import com.jetbrains.php.lang.PhpFileType
import com.jetbrains.php.testFramework.run.PhpDefaultTestRunnerSettingsValidator
import com.jetbrains.php.testFramework.run.PhpDefaultTestRunnerSettingsValidator.PhpTestMethodFinder
import com.jetbrains.php.testFramework.run.PhpTestConfigurationProducer
import com.pestphp.pest.*
import com.pestphp.pest.getPestTestName
import com.pestphp.pest.isPestEnabled
import com.pestphp.pest.isPestTestFile
import com.pestphp.pest.isPestTestFunction
import com.pestphp.pest.isPestConfigurationFile

class PestRunConfigurationProducer : PhpTestConfigurationProducer<PestRunConfiguration?>(
VALIDATOR,
FILE_TO_SCOPE,
METHOD_NAMER,
METHOD
VALIDATOR,
FILE_TO_SCOPE,
METHOD_NAMER,
METHOD
) {
override fun getConfigurationFactory(): ConfigurationFactory = PestRunConfigurationType.getInstance()

Expand All @@ -35,7 +39,7 @@ class PestRunConfigurationProducer : PhpTestConfigurationProducer<PestRunConfigu
}

companion object {
private val METHOD = Condition<PsiElement> { element: PsiElement? ->
val METHOD = Condition<PsiElement> { element: PsiElement? ->
return@Condition element.isPestTestFunction()
}
private val METHOD_NAMER = Function<PsiElement, String?> { element: PsiElement? ->
Expand All @@ -48,16 +52,16 @@ class PestRunConfigurationProducer : PhpTestConfigurationProducer<PestRunConfigu
null
}
val VALIDATOR = PhpDefaultTestRunnerSettingsValidator(
setOf<FileType>(PhpFileType.INSTANCE, XmlFileType.INSTANCE).toList(),
PhpTestMethodFinder { file: PsiFile, _: String ->
if (file.isPestConfigurationFile()) {
return@PhpTestMethodFinder true
}
setOf<FileType>(PhpFileType.INSTANCE, XmlFileType.INSTANCE).toList(),
PhpTestMethodFinder { file: PsiFile, _: String ->
if (file.isPestConfigurationFile()) {
return@PhpTestMethodFinder true
}

file.isPestTestFile()
},
false,
false
file.isPestTestFile()
},
false,
false
)
}
}
}
3 changes: 2 additions & 1 deletion src/main/kotlin/com/pestphp/pest/types/BaseTypeProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.jetbrains.php.lang.psi.elements.ParameterList
import com.jetbrains.php.lang.psi.elements.Variable
import com.jetbrains.php.lang.psi.elements.impl.FunctionReferenceImpl

@Suppress("UnnecessaryAbstractClass")
abstract class BaseTypeProvider {
protected fun PsiElement?.isThisVariableInPestTest(): Boolean {
if ((this as? Variable)?.name != "this") return false
Expand All @@ -29,4 +30,4 @@ abstract class BaseTypeProvider {
companion object {
private val PEST_TEST_FUNCTION_NAMES: Set<String> = setOf("it", "test")
}
}
}
31 changes: 18 additions & 13 deletions src/main/kotlin/com/pestphp/pest/types/ThisFieldTypeProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ package com.pestphp.pest.types
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import com.jetbrains.php.lang.psi.elements.*
import com.jetbrains.php.lang.psi.elements.AssignmentExpression
import com.jetbrains.php.lang.psi.elements.FieldReference
import com.jetbrains.php.lang.psi.elements.PhpTypedElement
import com.jetbrains.php.lang.psi.elements.Statement
import com.jetbrains.php.lang.psi.elements.Variable
import com.jetbrains.php.lang.psi.elements.PhpNamedElement
import com.jetbrains.php.lang.psi.elements.impl.FunctionReferenceImpl
import com.jetbrains.php.lang.psi.resolve.types.PhpType
import com.jetbrains.php.lang.psi.resolve.types.PhpTypeProvider4

class ThisFieldTypeProvider: BaseTypeProvider(), PhpTypeProvider4 {
class ThisFieldTypeProvider : BaseTypeProvider(), PhpTypeProvider4 {
override fun getKey(): Char {
return '\u0222'
}
Expand All @@ -21,16 +26,16 @@ class ThisFieldTypeProvider: BaseTypeProvider(), PhpTypeProvider4 {
val fieldName = fieldReference.name ?: return null

return psiElement.containingFile.firstChild.children
.filterIsInstance<Statement>()
.mapNotNull { it.firstChild }
.filterIsInstance<FunctionReferenceImpl>()
.filter { PEST_BEFORE_FUNCTION_NAMES.contains(it.name) }
.mapNotNull { it.parameterList?.getParameter(0) }
.flatMap { PsiTreeUtil.findChildrenOfType(it, AssignmentExpression::class.java) }
.filter { isNeededFieldReference(it.variable, fieldName) }
.mapNotNull { it.value }
.filterIsInstance<PhpTypedElement>()
.firstOrNull()?.type
.filterIsInstance<Statement>()
.mapNotNull { it.firstChild }
.filterIsInstance<FunctionReferenceImpl>()
.filter { PEST_BEFORE_FUNCTION_NAMES.contains(it.name) }
.mapNotNull { it.parameterList?.getParameter(0) }
.flatMap { PsiTreeUtil.findChildrenOfType(it, AssignmentExpression::class.java) }
.filter { isNeededFieldReference(it.variable, fieldName) }
.mapNotNull { it.value }
.filterIsInstance<PhpTypedElement>()
.firstOrNull()?.type
}

private fun isNeededFieldReference(psiElement: PsiElement?, fieldName: String): Boolean {
Expand All @@ -54,4 +59,4 @@ class ThisFieldTypeProvider: BaseTypeProvider(), PhpTypeProvider4 {
companion object {
private val PEST_BEFORE_FUNCTION_NAMES: Set<String> = setOf("beforeEach", "beforeAll")
}
}
}
4 changes: 2 additions & 2 deletions src/main/kotlin/com/pestphp/pest/types/ThisTypeProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.jetbrains.php.lang.psi.elements.PhpNamedElement
import com.jetbrains.php.lang.psi.resolve.types.PhpType
import com.jetbrains.php.lang.psi.resolve.types.PhpTypeProvider4

class ThisTypeProvider: BaseTypeProvider(), PhpTypeProvider4 {
class ThisTypeProvider : BaseTypeProvider(), PhpTypeProvider4 {
override fun getKey(): Char {
return '\u0221'
}
Expand All @@ -28,4 +28,4 @@ class ThisTypeProvider: BaseTypeProvider(), PhpTypeProvider4 {
companion object {
private val TEST_CASE_TYPE = PhpType().add("\\PHPUnit\\Framework\\TestCase")
}
}
}
Loading

0 comments on commit b4a7aa9

Please sign in to comment.