Writing compiler test

I'm building a plugin supporting an in-house language. We've covered most of the functionality with tests, but I am currently struggling with testing the custom compiler using JPS. 

I am trying to set up the following simple test:

  • create a project, add 1 or more modules to it
  • populate modules with files
  • run a file/module/project compilation using CompilerTester
  • perform assertions on returned compiler messages 

 

As some of the tests will be multi-module, the tests must be heavy as per https://www.jetbrains.org/intellij/sdk/docs/basics/testing_plugins/light_and_heavy_tests.html. My setUp method looks as follows:


override fun setUp() {
super.setUp()

val projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(name)
val moduleFixtureBuilder = projectBuilder.addModule(EmptyModuleFixtureBuilder::class.java)
projectFixture = IdeaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.fixture)
}

I don't use JavaModuleFixtureBuilder, as:

  • this is not a JVM-based language
  • trying to do so ends up in exception
java.lang.AssertionError: interface com.intellij.testFramework.builders.JavaModuleFixtureBuilder
at com.intellij.testFramework.fixtures.impl.HeavyTestFixtureBuilderImpl.addModule(HeavyTestFixtureBuilderImpl.java:37)

The next step is to add some files:

projectFixture.configureByFiles("simple/bar.xxx", "simple/baz.xxx", "simple/foo.xxx")

Firstly, this looks suspicious as I should be adding files to the module, and not to the project - but ModuleFixture has no useful methods for adding files. How do I associate files to a module?

Secondly, I'm getting an exception

java.lang.AssertionError: setUp() hasn't been called

at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.assertInitialized(CodeInsightTestFixtureImpl.java:700)
at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.configureByFilesInner(CodeInsightTestFixtureImpl.java:1295)
at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.configureByFiles(CodeInsightTestFixtureImpl.java:1313)

 Alright, let's call projectFixture.setUp():

java.lang.IllegalStateException: Previous test did not call assertPointersAreDisposed() - see 'Caused by:' for its stacktrace

at com.intellij.openapi.vfs.impl.VirtualFilePointerTracker.storePointers(VirtualFilePointerTracker.java:60)
at com.intellij.openapi.vfs.impl.VirtualFilePointerTracker.<init>(VirtualFilePointerTracker.java:54)
at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.setUp(CodeInsightTestFixtureImpl.java:1217)

This seems like some initialization has already been done by super.setUp(), however that one is vital. What I am doing wrong? How do I setup a heavy test case?

 

I tried to get at least a light test working, but that didn't go well either

fun testSimple() {
myFixture.configureByFiles("simple/bar.xxx", "simple/baz.xxx", "simple/foo.xxx")

val tester = CompilerTester(project, listOf(module), null)
val messages = tester.compileModule(module)
tester.tearDown()
println(messages)
}

gets me the following error in tearDown.

com.intellij.openapi.util.TraceableDisposable$DisposalException: Virtual pointer 'file:///private/var/folders/_s/l5p5pvss3c52fk5s0sh9xr7h0000gn/T/unitTest_foo1313/unitTest/out' hasn't been disposed: --------------Creation trace: 
java.lang.Throwable
at com.intellij.openapi.util.TraceableDisposable.<init>(TraceableDisposable.java:31)
at com.intellij.openapi.vfs.impl.VirtualFilePointerImpl.<init>(VirtualFilePointerImpl.java:38)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.getOrCreate(VirtualFilePointerManagerImpl.java:359)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.create(VirtualFilePointerManagerImpl.java:244)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.createDirectoryPointer(VirtualFilePointerManagerImpl.java:753)
at com.intellij.openapi.vfs.impl.VirtualFilePointerContainerImpl.lambda$addAllJarDirectories$4(VirtualFilePointerContainerImpl.java:410)
at com.intellij.util.containers.ContainerUtil.map(ContainerUtil.java:2098)
at com.intellij.openapi.vfs.impl.VirtualFilePointerContainerImpl.addAllJarDirectories(VirtualFilePointerContainerImpl.java:410)
at com.intellij.openapi.roots.impl.ProjectRootManagerComponent.collectWatchRoots(ProjectRootManagerComponent.java:250)
at com.intellij.openapi.roots.impl.ProjectRootManagerComponent.lambda$null$1(ProjectRootManagerComponent.java:142)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:821)
at com.intellij.openapi.application.ReadAction.compute(ReadAction.java:69)
at com.intellij.openapi.roots.impl.ProjectRootManagerComponent.lambda$addRootsToWatch$3(ProjectRootManagerComponent.java:142)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at com.intellij.util.SameThreadExecutorService.execute(SameThreadExecutorService.java:48)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
at com.intellij.openapi.roots.impl.ProjectRootManagerComponent.addRootsToWatch(ProjectRootManagerComponent.java:141)
at com.intellij.openapi.roots.impl.ProjectRootManagerComponent.fireRootsChangedEvent(ProjectRootManagerComponent.java:203)
at com.intellij.openapi.roots.impl.ProjectRootManagerImpl.fireRootsChanged(ProjectRootManagerImpl.java:393)
at com.intellij.openapi.roots.impl.ProjectRootManagerImpl.access$200(ProjectRootManagerImpl.java:35)
at com.intellij.openapi.roots.impl.ProjectRootManagerImpl$BatchSession.rootsChanged(ProjectRootManagerImpl.java:93)
at com.intellij.openapi.roots.impl.ProjectRootManagerImpl.makeRootsChange(ProjectRootManagerImpl.java:336)
at com.intellij.openapi.module.impl.ModuleManagerImpl.commitModel(ModuleManagerImpl.java:1005)
at com.intellij.openapi.module.impl.ModuleManagerImpl.access$1500(ModuleManagerImpl.java:64)
at com.intellij.openapi.module.impl.ModuleManagerImpl$ModuleModelImpl.commitWithRunnable(ModuleManagerImpl.java:906)
at com.intellij.openapi.module.impl.ModuleManagerImpl$ModuleModelImpl.access$1200(ModuleManagerImpl.java:668)
at com.intellij.openapi.module.impl.ModuleManagerImpl.commitModelWithRunnable(ModuleManagerImpl.java:659)
at com.intellij.openapi.roots.impl.ModifiableModelCommitterServiceImpl.multiCommit(ModifiableModelCommitterServiceImpl.java:34)
at com.intellij.openapi.roots.impl.ModifiableModelCommitter.multiCommit(ModifiableModelCommitter.java:20)
at com.intellij.openapi.roots.impl.ModuleRootManagerImpl.commitModel(ModuleRootManagerImpl.java:167)
at com.intellij.openapi.roots.impl.RootModelImpl.commit(RootModelImpl.java:377)
at com.intellij.openapi.application.WriteAction.run(WriteAction.java:98)
at com.intellij.openapi.roots.ModuleRootModificationUtil.lambda$updateModel$9(ModuleRootModificationUtil.java:147)
at com.intellij.openapi.application.impl.ApplicationImpl.invokeAndWait(ApplicationImpl.java:519)
at com.intellij.openapi.application.impl.ApplicationImpl.invokeAndWait(ApplicationImpl.java:532)
at com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel(ModuleRootModificationUtil.java:145)
at com.intellij.openapi.roots.ModuleRootModificationUtil.setModuleSdk(ModuleRootModificationUtil.java:121)
at com.intellij.testFramework.CompilerTester.lambda$new$0(CompilerTester.java:95)
at com.intellij.openapi.command.WriteCommandAction$BuilderImpl$1.run(WriteCommandAction.java:110)
at com.intellij.openapi.application.RunResult.run(RunResult.java:35)
at com.intellij.openapi.command.WriteCommandAction.lambda$null$1(WriteCommandAction.java:251)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:885)
at com.intellij.openapi.command.WriteCommandAction.lambda$performWriteCommandAction$2(WriteCommandAction.java:250)
at com.intellij.openapi.command.WriteCommandAction.lambda$doExecuteCommand$4(WriteCommandAction.java:308)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:220)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:188)
at com.intellij.openapi.command.WriteCommandAction.doExecuteCommand(WriteCommandAction.java:310)
at com.intellij.openapi.command.WriteCommandAction.performWriteCommandAction(WriteCommandAction.java:249)
at com.intellij.openapi.command.WriteCommandAction.execute(WriteCommandAction.java:230)
at com.intellij.openapi.command.WriteCommandAction$BuilderImpl.run(WriteCommandAction.java:112)
at com.intellij.testFramework.CompilerTester.<init>(CompilerTester.java:90)

again some issue with VirtualFilePointers.

What's worse -- the CompileScope doesn't contain any files, so no compilation is performed at all (perhaps you can't even use CompileTester in light test)?

Any pointers on how to get this working?

 

Please sign in to leave a comment.