Test fixture to mimic a gradle project
Hi,
I'd like to discover the gradle version of a project in order to patch the gradle file with custom dependencies. However depending on the version of Gradle the dependency scope has to be be declared as `compile` for older gradle, or as `implementation` for later versions. I have identified the following APIs.
* org.jetbrains.plugins.gradle.util.GradleUtil#getGradleVersion(com.intellij.openapi.project.Project, java.lang.String)
* org.jetbrains.plugins.gradle.service.GradleInstallationManager#getGradleVersion(String)
I believe I need the first one. However I am not sure how to unit test the behaviour of this code. I have looked at some tests in the external system, from what I have seen the setup seems convoluted. But if I use something simple as that the gradle version is not what I expect.
public class GradleVersionTest extends LightJavaCodeInsightFixtureTestCase4 {
@Test
public void can_get_correct_gradle_version() {
PsiFile buildGradle = getFixture().configureByText("build.gradle", "");
getFixture().addFileToProject("gradle/wrapper/gradle-wrapper.properties", "distributionBase=GRADLE_USER_HOME\n" +
"distributionPath=wrapper/dists\n" +
"distributionUrl=https\\://services.gradle.org/distributions/gradle-7.2-bin.zip\n" +
"zipStoreBase=GRADLE_USER_HOME\n" +
"zipStorePath=wrapper/dists\n");
GradleVersion gradleVersion = GradleUtil.getGradleVersion(getFixture().getProject(), buildGradle);
Assert.assertEquals(GradleVersion.version("7.2"), gradleVersion);
}
}
This test fails as the the returned version is 6.8 instead of 7.2.
Also I would like to identify the DSL, Kotlin or Gradle, currently I am using the name of the file, is there other way that make use of the IntelliJ API ?
Thank you in advance.
Please sign in to leave a comment.
AFAIU it fails because you do not link/import the test project via External System API. see org.jetbrains.plugins.gradle.importing.GradleImportingTestCase
To distinguish Groovy/Kotlin, use com.android.tools.idea.gradle.dsl.api.GradleBuildModel and then switch depending on getPsiFile() instance.
Yes that is likely possible. But neither `GradleImportingTestCase`, `ExternalSystemImportingTestCase`, or `ExternalSystemTestCase` are available as they don't seem to be part of the `testFramework`. Which is why I tried something simpler using bits of the external system tests like
or
But I'm not yet successful yet. I'll try with a `HeavyPlatformTestCase`.
I'm not sure if it is relevant, but the build descriptor of my plugin declares this IJ plugin.
Yes, please switch to heavy tests. These test classes are not published separately and/or are part of specific plugin and thus "local".
Ok I got this to work. Thank you !
Hi Yann Cebron
I have a question around testing. I'm not quite sure why in the heavy test the `PsiFile` modification don't get written to disk.
The test I have written extending `LightJavaCodeInsightFixtureTestCase` work as expected.
However since I'm moving these to the `HeavyPlatformTestCase`, the setup and assertion is different. In particular the changes perfomed to the `PsiFile` reprensenting `build.gradle` are not persisted to disk (the PSI changes are performed within a `WriteCommandAction.writeCommandAction`). And I am asserting on the file on disk (eg via `Files.readString(buildGradle.toNioPath())`) in the fixture temporary project.
I have tried these API in the test code to persist the change to disk without success.
* `PsiDocumentManager.getInstance(getProject()).commitAllDocuments()`
* `PlatformTestUtil.saveProject(getProject())`
I do have a workaround in the new heavy test by using either the `Document` or the `PsiFile` `getText` method, which has the modification.
I think the tested code is OK, but I don't get what I'm missing in the test, maybe I missed something while analyzing `ExternalSystemTestCase`.
Thanks in advance.