Is it possible to have multiple source roots in unit tests?
In the plugin I'm developing, I need to verify that my custom action is available only in the test JVM source root (JavaSourceRootType.TEST_SOURCE).
By default, the LightProjectDescritor in the LightJavaCodeInsightFixtureTestCase will create the temp:///src directory and mark it as a source root.
For my test to be as close to reality as possible, I wanted to create two - a src/main/java source root and a src/test/groovy test source root.
The test would then verify that the action is available in one but not in the other source root.
I am not sure whether this is even possible. The LightTempDirTestFixtureImpl relies on a single source root only. I can override the LightProjectDescritor, LightTempDirTestFixtureImpl and create a custom IdeaTestExecutionPolicy, but this seems a bit complicated and I am not sure if this is the right way to go.
Also, I am not sure where is the right place to register my source roots and how to create them. The LightProjectDescriptor#createSourceRoot only seems to accept a directory name rather than a path.
Please sign in to leave a comment.
You can simply add test sources directory programmatically in the specific test
Or provide custom
LightProjectDescriptorand overrideconfigureModule()Thanks Yann Cebron for the hints!
I aim to do this setup for all tests, so the
LightProjectDescriptorwill be the way to go.There is one catch though. I wanted the new
SpockLightProjectDescriptorto be a standalone class, so I added the fixture as a constructor parameter.However, there is a circular dependency now
SpockLightProjectDescriptorneedsmyFixturebutmyFixtureisnulluntil theLightProjectDescriptor.setup()is called.LightProjectDescriptor.setup()callsgetProjectDescriptor().I can workaround it of course, but I was wondering if I could do all the stuff in the
SpockLightProjectDescriptorwithout the fixture.myFixture.testRootDisposablewould mean calling an internal API(module.project as ProjectEx).earlyDisposable).When I commented out the suggested
Disposer.register(myFixture.getTestRootDisposable(), () -> PsiTestUtil.removeSourceRoot(getModule(), testRootDir));code, I thought that meant the source root wouldn't be removed after every test. However, each test seems to start fresh with only thetemp://srcdirectory setup.There is another problem. If I follow your steps and create
src/main/java, the action is available even though it's not in a real IntelliJ instance.When debugging, the
CreateTemplateInPackageAction#isAvailable()returnstruein tests whereas in real instances it returnsfalsewhen the action is run in thesrc/main/javadirectory.Debugging more, the difference can be spotted in the attached pictures:
fileSet.rootpoints to thesrc/main/javaorsrc/main/kotlin. All good here.fileSet.data.customContentRootdiffer. For the test it'snullbut in IntelliJ, it points tosrc/main.It seems like the test setup is not the same as in real IntelliJ.
Sorry, but it's quite impossible to understand and reproduce your issues without access to the full sources.
Yeah, I understand. The sources are here: https://github.com/lobodpav/spock-intellij-plugin
Replication steps:
io.github.lobodpav.spock.action.NewSpockSpecificationActionIdeaSpec#The action is available only when Groovy and Spock are on the classpathtest.isAvailablemethod returnstrueformain/java(which is incorrect and the action is unavailable in real IntelliJ).