<commit_before>package ch.fhnw.ima.saav.controller

import ch.fhnw.ima.saav.controller.SaavController.{AnalysisHandler, _}
import ch.fhnw.ima.saav.model._
import ch.fhnw.ima.saav.model.domain.AnalysisBuilder
import diode.RootModelRW
import org.scalatest.{FlatSpec, _}

class SaavControllerSpec extends FlatSpec with Matchers {

  val model = SaavModel().model

  def createHandler = new AnalysisHandler(new RootModelRW(model))

  it should s"handle ${AnalysisImportInProgressAction.getClass.getSimpleName}" in {
    val result = createHandler.handle(AnalysisImportInProgressAction(0.9f))
    result.newModelOpt match {
      case Some(Left(NoDataModel(ImportInProgress(progress)))) =>
        progress shouldBe 0.9f
      case _ =>
        fail("Unexpected action result")
    }
  }

  it should s"handle ${AnalysisImportFailedAction.getClass.getSimpleName}" in {
    val throwable = new Throwable("test")
    val result = createHandler.handle(AnalysisImportFailedAction(throwable, logToConsole = false))
    result.newModelOpt match {
      case Some(Left(NoDataModel(ImportFailed(t)))) =>
        t shouldBe throwable
      case _ =>
        fail("Unexpected action result")
    }
  }

  it should s"handle ${AnalysisReadyAction.getClass.getSimpleName}" in {
    val analysis = AnalysisBuilder.personAnalysisBuilder.build
    val result = createHandler.handle(AnalysisReadyAction(analysis))
    result.newModelOpt match {
      case Some(Right(DataModel(actualAnalysis, _, selectedEntities, None))) =>
        actualAnalysis shouldBe analysis
        selectedEntities should contain allElementsOf analysis.entities
      case _ =>
        fail("Unexpected action result")
    }
  }

}<commit_msg>#18: Add tests for SelectionAndPinningHandler<commit_after>package ch.fhnw.ima.saav.controller

import ch.fhnw.ima.saav.controller.SaavController.{AnalysisHandler, _}
import ch.fhnw.ima.saav.model._
import ch.fhnw.ima.saav.model.domain.AnalysisBuilder
import ch.fhnw.ima.saav.model.domain.Entity.Person
import diode.RootModelRW
import org.scalatest._

import scala.collection.immutable.ListSet

class SaavControllerSpec extends FunSpec with Matchers {

  def analysisHandler = new AnalysisHandler(new RootModelRW(SaavModel().model))

  def selectionAndPinningHandler(initialModel: SelectionAndPinning) = new SelectionAndPinningHandler(new RootModelRW(initialModel))

  def failOnUnexpectedAction = fail("Unexpected action result")

  describe(s"Handling ${AnalysisImportInProgressAction.getClass.getSimpleName}") {
    it("should wire a progress value") {
      val result = analysisHandler.handle(AnalysisImportInProgressAction(0.9f))
      result.newModelOpt match {
        case Some(Left(NoDataModel(ImportInProgress(progress)))) =>
          progress shouldBe 0.9f
        case _ => failOnUnexpectedAction
      }
    }
  }

  describe(s"Handling ${AnalysisImportFailedAction.getClass.getSimpleName}") {
    it("should wire a throwable") {
      val throwable = new Throwable("test")
      val result = analysisHandler.handle(AnalysisImportFailedAction(throwable, logToConsole = false))
      result.newModelOpt match {
        case Some(Left(NoDataModel(ImportFailed(t)))) =>
          t shouldBe throwable
        case _ => failOnUnexpectedAction
      }
    }
  }

  describe(s"Handling ${AnalysisReadyAction.getClass.getSimpleName}") {
    it("should wire a data model") {
      val analysis = AnalysisBuilder.projectAnalysisBuilder.build
      val result = analysisHandler.handle(AnalysisReadyAction(analysis))
      result.newModelOpt match {
        case Some(Right(DataModel(actualAnalysis, _, selectedEntities, None))) =>
          actualAnalysis shouldBe analysis
          selectedEntities.toSeq == analysis.entities
        case _ => failOnUnexpectedAction
      }
    }
  }

  describe(s"Handling ${UpdateEntitySelectionAction.getClass.getSimpleName}") {
    it("should wire selected entities") {
      val handler = selectionAndPinningHandler(SelectionAndPinning())
      val selectedEntities = Seq(Person("x"), Person("y"))
      val result = handler.handle(UpdateEntitySelectionAction(selectedEntities, isSelected = true))
      result.newModelOpt match {
        case Some(SelectionAndPinning(actualSelectedEntities, actualPinned)) =>
          actualSelectedEntities.toSeq == selectedEntities
          actualPinned shouldBe empty
        case _ => failOnUnexpectedAction
      }
    }
    it("should clear pinning if entity is no longer selected") {
      val anEntity = Person("x")
      val handler = selectionAndPinningHandler(SelectionAndPinning(pinned = Some(anEntity)))
      val result = handler.handle(UpdateEntitySelectionAction(Seq(), isSelected = false))
      result.newModelOpt match {
        case Some(SelectionAndPinning(actualSelectedEntities, actualPinned)) =>
          actualSelectedEntities shouldBe empty
          actualPinned shouldBe empty
        case _ => failOnUnexpectedAction
      }
    }
    it("should not touch pinning if entity is still selected") {
      val anEntity = Person("x")
      val handler = selectionAndPinningHandler(SelectionAndPinning(pinned = Some(anEntity)))
      val result = handler.handle(UpdateEntitySelectionAction(Seq(anEntity), isSelected = true))
      result.newModelOpt match {
        case Some(SelectionAndPinning(actualSelectedEntities, actualPinned)) =>
          actualSelectedEntities shouldBe ListSet(anEntity)
          actualPinned shouldBe Some(anEntity)
        case _ => failOnUnexpectedAction
      }
    }
  }

  describe(s"Handling ${UpdateEntityPinningAction.getClass.getSimpleName}") {
    it("should wire a pinned entity") {
      val handler = selectionAndPinningHandler(SelectionAndPinning())
      val pinnedEntity = Some(Person("x"))
      val result = handler.handle(UpdateEntityPinningAction(pinnedEntity))
      result.newModelOpt match {
        case Some(SelectionAndPinning(_, actualPinnedEntity)) =>
          actualPinnedEntity shouldBe pinnedEntity
        case _ => failOnUnexpectedAction
      }
    }
  }

}
{'fraction_non_alphanumeric': 0.09060736807168934, 'fraction_numerical': 0.001659475605708596, 'mean_word_length': 3.9079804560260585, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1694505', 'n_tokens_mistral': 1626, 'n_tokens_neox': 1631, 'n_words': 334}