package org.jetbrains.plugins.scala
package annotator

import org.intellij.lang.annotations.Language
import org.jetbrains.plugins.scala.annotator.element.ScTypedExpressionAnnotator
import org.jetbrains.plugins.scala.base.SimpleTestCase
import org.jetbrains.plugins.scala.extensions._
import org.jetbrains.plugins.scala.lang.psi.api.expr.ScTypedExpression

class TypedExpressionAnnotatorTest extends SimpleTestCase {
  private final val Header = "class A; class B; object A extends A; object B extends B\n"

  def testFine(): Unit = {
    assertMatches(messages("A: A")) {
      case Nil =>
    }
  }

  def testTypeMismatch(): Unit = {
    assertMatches(messages("B: A")) {
      case Error("A", UpcastingError()) :: Nil =>
    }
  }

  def testTypeMismatchMessage(): Unit = {
    assertMatches(messages("B: A")) {
      case Error(_, "Cannot upcast B.type to A") :: Nil =>
    }
  }

  //todo: requires Function1 trait in scope
  /*def testImplicitConversion {
    assertMatches(messages("implicit def toA(b: B) = A; B: A")) {
      case Nil =>
    }
  }*/


  def messages(@Language(value = "Scala", prefix = Header) code: String): List[Message] = {
    val file = (Header + code).parse
    val expression = file.depthFirst().findByType[ScTypedExpression].get

    implicit val mock: AnnotatorHolderMock = new AnnotatorHolderMock(file)
    ScTypedExpressionAnnotator.annotate(expression)
    mock.annotations
  }

  private val UpcastingError = ContainsPattern("Cannot upcast")
}

{'avg_line_length': 29.64, 'max_line_length': 91, 'alphanum_fraction': 0.7064777327935222, 'licenses': ['Apache-2.0'], 'repository_name': 'FogInTheFrog/intellij-scala', 'path': 'scala/scala-impl/test/org/jetbrains/plugins/scala/annotator/TypedExpressionAnnotatorTest.scala', 'size': 1482, 'lang': 'Scala'}