Is it possible to piTest a removed call to scala/MatchError::<init>

146 views Asked by At

I am curious to know if it is possible to fully test following code with Pitest/ScalaCheck

Methods to test:

  def insertionSort(xs: List[Int]): List[Int] = xs match {
    case Nil => Nil
    case a :: as => insert(a, insertionSort(as))
  }

  private def insert(x: Int, xs: List[Int]): List[Int] = xs match {
    case Nil => List(x)
    case a :: as =>
      if (a >= x) x :: xs
      else a :: insert(x, as)
  }

Tests provided:

@RunWith(classOf[ScalaCheckJUnitPropertiesRunner])
class InsertionSortTests extends Properties("InsertionSortTests") {
   private val nonEmptyIntListGen: Gen[List[Int]] = Gen.nonEmptyListOf(Arbitrary.arbitrary[Int])

  property("ordered") = forAll(nonEmptyIntListGen) { (xs: List[Int]) =>
    val sorted = insertionSort(xs)
    xs.nonEmpty ==> xs.indices.tail.forall((i: Int) => sorted(i - 1) <= sorted(i))
  }

  property("permutation") = forAll { (xs: List[Int]) =>
    val sorted = insertionSort(xs)
    def count(a: Int, as: List[Int]) = as.count(_ == a)
    xs.forall((x: Int) => count(x, xs) == count(x, sorted))
  }
}

I am getting full coverage except following lines:

def insertionSort(xs: List[Int]): List[Int] = xs match {
private def insert(x: Int, xs: List[Int]): List[Int] = xs match {

I am getting following error on both lines:

1. removed call to scala/MatchError::<init> → NO_COVERAGE
1

There are 1 answers

2
Levi Ramsey On BEST ANSWER

The call to scala/MatchError is synthesized by the compiler for the case where the match fails (it's the call to MatchError's constructor which gets thrown if none of the cases in the pattern match apply). Since your pattern match is in fact exhaustive, there's no way for the match to fail, ergo there's no way in Scala to force the match to fail (this is assuming that you're using the standard library List; if you're using your own implementation of List, perhaps it's not sealed?)

It's perhaps a Scala compiler bug that it generates bytecode for failed pattern matches which can't fail.

I'm not familiar with pitest, but it's likely that it doesn't understand Scala (or the higher level semantic meaning of the bytecode emitted by the Scala compiler); tools which rely on bytecode manipulation are likely to not always work as they would for Java with Scala.