JUnit and accessing resources in Kotlin


#1

Hi,

I recently ported an IntelliJ language plugin from Java to Kotlin, which was made fairly easy thanks to the code translator :slight_smile:. The project is herehttp://github.com/bbarker/IntelliJATS; the latest commit should be the one that converted most of the code to Kotlin.

There is one unresolve issue related to loading resources (i.e. source files in the supported language for testing the lexer). I try to do this in the ATSLexerAdapterTest.kt file; this file uses a function called getFileAsString, which is successfully used to load the demo source used in the Plugin configuration pane. Here is the source for that function:

inline fun getFileAsString<reified T>(relPath: String): String {
    val fileStream = javaClass<T>().getClassLoader().getResourceAsStream(relPath)
    val fileReader: InputStreamReader? = fileStream.reader()
    val path: String? = javaClass<T>().getClassLoader().getResource(relPath)?.getPath()
    println(path ?: "File not found!" )
    return fileReader?.readText() ?: "// error: file not found or null"
}

However, when I try to run ATSLexerAdapterTest, I get the error pasted below on the following line:

 
var settingsPageDemo = getFileAsString<ATSLexerAdapterTest>("/test/Resources/list_vt_quicksort.dats")

Error:

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.io.IoPackage$IOStreams$91bf559d.reader, parameter $receiver
at kotlin.io.IoPackage$IOStreams$91bf559d.reader(IOStreams.kt)
at kotlin.io.IoPackage$IOStreams$91bf559d.reader$default(IOStreams.kt:27)
at kotlin.io.IoPackage.reader$default(Unknown Source)
at test.com.atslangplugin.ATSLexerAdapterTest.<init>(ATSLexerAdapterTest.kt:33)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:195)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

A quick google search suggests this may be more-or-less a Kotlin-specific issue, so I thought I’d post here first.

Thanks!


#2

As the exception message says, you're passing a null to a receiver parameter of "reader" extension function. This means that "getResourceAsStream" one line earlier returned null, so your resource is not found, probably because of a misconfiguration or wrong classpath.


#3

Ah ... woops. I suppose somehow I was thinking I'd tried all the viable possibilities, there, but I didn't: I'm still a bit confused by what getResource*() functions expect, but I found the right combination. Not a Kotlin problem anyway. This helped me spot a few more issues that have now been fixed, so the unit tests work!