idea-plugin / arrow.meta.ide.testing.env / ideTest

ideTest

fun <F : IdeSyntax, A> ideTest(myFixture: CodeInsightTestFixture, ctx: F = IdeEnvironment as F, tests: IdeEnvironment.() -> List<IdeTest<F, A>>): Unit

This extension runs each test for selected editor features. Each Test class has to extend IdeTestSetUp, in order to spin-up the underlying Intellij Testing Platform at runtime. That also insures that the property myFixture is properly instantiated.

class ExampleTest: IdeTestSetUp() {
  /** test features **/
}

One IdeTest is composed by the source code, a test described with algebras in IdeTestSyntax, and the expected result. Based on a dummy IdePlugin

class MyIdePlugin : IdeSyntax

a general schema looks like this:

import arrow.meta.ide.dsl.IdeSyntax
import arrow.meta.ide.testing.IdeTest
import arrow.meta.ide.testing.Source
import arrow.meta.ide.testing.env.IdeTestSetUp
import arrow.meta.ide.testing.env.ideTest
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
import org.junit.Test
//sampleStart
class ExampleTest : IdeTestSetUp() {
  @Test
  fun `general test schema`(): Unit =
    ideTest(
      myFixture = myFixture, // the IntelliJ test environment spins up [myFixture] automatically at runtime.
      ctx = MyIdePlugin() // add here your ide plugin, to get dependencies and created features in the scope of [test] and [result].
    ) {
      listOf<IdeTest<MyIdePlugin, Unit>>( // type inference is not able to resolve the types here
        IdeTest(
          "val exampleCode = 2",
          test = { code: Source, myFixture: CodeInsightTestFixture, ctx: MyIdePlugin ->
            /**
             * In addition to the parameters above the [IdeEnvironment] is in Scope, which bundles test operations in [IdeTestSyntax]
             * over the [IdeSyntax]. [IdeTestSyntax] composes a symmetric API over [IdeSyntax] in respect to tests.
             * That means an interface such as [LineMarkerSyntax] from the [IdeSyntax] is tested with [LineMarkerTestSyntax] from the [IdeTestSyntax].
             * Furthermore, one can use the scope of [ctx] to use declared dependencies and features in the test.
             **/
              },
              result = resolves("Any result is accepted") // here we define what behavior is expected
            ) // ... you may add more test suit's for the same or related ide feature with different code examples and test's
          )
        }
    }
    //sampleEnd
    class MyIdePlugin : IdeSyntax

Given the helloWorld ide plugin, one concrete example may look like this:

@Test
fun `hello World LineMarker is displayed`(): Unit =
  ideTest(
    myFixture = myFixture,
    ctx = IdeMetaPlugin()
  ) {
    listOf<IdeTest<IdeMetaPlugin, LineMarkerDescription>>(
      IdeTest(
        code = """
        | fun helloWorld(): String =
        |   "Hello world!"
        """.trimIndent(),
        test = { code: Source, myFixture: CodeInsightTestFixture, ctx ->
          collectLM(code, myFixture, ArrowIcons.ICON1) // this collect's all visible LineMarkers in the editor for the given Icon
        },
        result = resolvesWhen("LineMarker Test for helloWorld") {
          it.lineMarker.size == 1 // we expect that there is only one lineMarker in our example code
        }
      )
    )
  }

The key in result is to define the shape of the expected outcome, whether the test represents a valid or invalid representation of A.

Parameters

myFixture - is a key component of the underlying Intellij Testing API.

ctx - is the plugin context if unspecified it will use the IdeEnvironment

See Also

runTest

Do you like Arrow?

Arrow Org
<