콘텐츠로 이동

2023 05 02

2023-05-02

Scala Test

  • Specs2
  • ScalaTests
    • PlaySpecification
      • Play specs2 specification.
      • This trait excludes some of the mixins provided in the default specs2 specification that clash with Play helpers methods.
      • It also mixes in the Play test helpers and types for convenience.

Scala Fragments

  • 다음과 같은 형식으로 테스트 진행 (beforeAll, afterAll 투입)
    override def map(fragments: => Fragments) =
        step(beforeAll()) ^ fragments ^ step(afterAll())
    
  • specs2-core
    package org.specs2
    package specification
    package core
    
    import scalaz.Monoid
    import scalaz.concurrent.Task
    import scalaz.stream._
    import Process._
    import Fragment._
    
    /**
    
     * Fragments of a specification
     *
    
     * It is implemented as a Process of Fragment in order to produce fragments
     * dynamically if necessary
     */
    case class Fragments(contents: Process[Task, Fragment]) {
      /** append one or several fragments to this process */
    
      def append(other: Fragment): Fragments                = append(Process(other))
      def append(others: Seq[Fragment]): Fragments          = append(Fragments(others:_*))
      def append(others: Fragments): Fragments              = append(others.contents)
      def appendLazy(other: =>Fragment): Fragments          = append(Process.eval(Task.delay(other)))
    
      /** prepend one or several fragments to this process */
    
      def prepend(other: Fragment): Fragments                = prepend(Process(other))
      def prepend(others: Fragments): Fragments              = prepend(others.contents)
      def prepend(others: Seq[Fragment]): Fragments          = prepend(Fragments(others:_*))
      def prependLazy(other: =>Fragment): Fragments          = prepend(Process.eval(Task.delay(other)))
    
      /** filter, map or flatMap the fragments */
    
      def when(condition: =>Boolean) = copy(contents = contents when emit(condition))
    
      def map(f: Fragment => Fragment)                                  = copy(contents = contents map f)
      def mapDescription(f: Description => Description)                 = map(_.updateDescription(f))
      def filter(predicate: Fragment => Boolean)                        = copy(contents = contents filter predicate)
    
      def update(f: Process[Task, Fragment] => Process[Task, Fragment]) = copy(contents = f(contents))
      def flatMap(f: Fragment => Process[Task, Fragment])               = copy(contents = contents flatMap f)
      def |> (other: Process1[Fragment, Fragment])                      = copy(contents = contents |> other)
      def append(other: Process[Task, Fragment]): Fragments             = copy(contents = contents fby other)
      def prepend(other: Process[Task, Fragment]): Fragments            = copy(contents = other fby contents)
    
      /** run the process to get all fragments */
      def fragments: IndexedSeq[Fragment] = contents.runLog.run
    
      /** run the process to get all texts */
      def texts = fragments.filter(isText)
    
      /** run the process to get all examples */
      def examples = fragments.filter(isExample)
    
      /** run the process to get all specification references as Fragments */
      def referenced = fragments.filter(isSpecificationRef)
    
      /** run the process to get all specification references */
      def specificationRefs = fragments.collect(specificationRef)
    
      /** run the process to get all specification see references */
      def seeReferences = fragments.collect(seeReference)
    
      /** run the process to get all specification link references */
      def linkReferences = fragments.collect(linkReference)
    
    
      /** strip the margin of all examples */
      def stripMargin: Fragments = stripMargin('|')
    
      /** strip the margin of all examples */
      def stripMargin(margin: Char): Fragments = mapDescription(_.stripMargin(margin))
    
      /** when 2 Text fragments are contiguous append them together to only make one */
      def compact = {
        val (text1, accumulated1) = fragments.foldLeft((None, Vector()): (Option[String], Seq[Fragment])) { case ((text, accumulated), fragment) =>
          fragment match {
            case Fragment(Text(t),l, e) if isText(fragment) =>
              (text.map(_+t).orElse(Some(t)), accumulated)
    
            case other =>
              text match {
                case Some(t1) => (None, accumulated ++ Seq(Fragment(Text(t1), Execution.NoExecution), other))
                case None     => (None, accumulated :+ other)
              }
          }
        }
        val compacted = text1.fold(accumulated1)(t => accumulated1 :+ Fragment(Text(t), Execution.NoExecution))
        Fragments(compacted:_*)
      }
    
    }
    
    object Fragments {
      /** empty sequence of fragments */
      val empty = Fragments()
    
      /** create fragments from a sequence of individual fragments */
      def apply(fragments: Fragment*): Fragments =
        Fragments(emitAll(fragments).toSource)
    
      implicit def FragmentsMonoid: Monoid[Fragments] = new Monoid[Fragments] {
        def zero : Fragments = Fragments.empty
    
        def append(fs1: Fragments, fs2: =>Fragments): Fragments =
          fs1.append(fs2)
      }
    
      /** iterate over elements to create a Fragments object */
      def foreach[T](seq: Seq[T])(f: T => Fragments): Fragments =
        seq.foldLeft(Fragments.empty)((res, cur) => res.append(f(cur)))
    }