All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.specs2.specification.TagsAssociation.scala Maven / Gradle / Ivy

There is a newer version: 3.7
Show newest version
package org.specs2
package specification

import TagFragments._
import scalaz.{syntax, Foldable, Scalaz}
import Scalaz._
import collection.Iterablex._
import collection.Seqx._

trait TagsAssociation {
  /**
   * Associate each fragment with its tag according to the "tags" method
   */
  private[specs2]
  def tagFragments(fragments: Seq[Fragment]): Seq[(Fragment, TagFragment)] = fragments zip tags(fragments)

  /**
   * From a Seq of Fragments create a seq of corresponding tags for each fragment, considering that:
   *
   *  - a `TaggedAs` fragment is applicable to the the previous fragment
   *  - a `Tag` fragment is applicable to the the next fragment
   *  - a `AsSection` fragment is applicable to the the previous fragment to the next `AsSection` fragment with the same name
   *  - a `Section` fragment is applicable to the the next fragment to the next `Section` fragment with the same name
   */
  private[specs2]
  def tags(fragments: Seq[Fragment]): Seq[TagFragment] = {
    val (tags, _) =
    fragments.foldLeft((Vector(): Seq[TagFragment], (Seq(): Seq[TagFragment], AlwaysWhenNoIncludeTag: TagFragment))) { (res, cur) =>
      val (tagged, (sectionTags, previousTag)) = res
      cur match {
        case t1: TagFragment if !t1.isSection =>
          if (t1.isTaggingNext) (tagged :+ t1,                   (sectionTags, previousTag |+| t1))
          else                  (tagged.mapLast(_ |+| t1) :+ t1, (sectionTags, previousTag))

        /** section for the next fragment */
        case t1: TagFragment =>
          val endTags        = sectionTags.filter(_.names.exists(t1.names.contains))
          val startTags      = sectionTags.map(t => t.removeNames(t1.names)).filterNot(_.names.isEmpty)
          val newSectionTags = if (endTags.isEmpty) startTags :+ t1 else startTags
          val tagToApply     = startTags.sumr |+| t1

          if (t1.isTaggingNext) (tagged :+ tagToApply,                   (newSectionTags, t1))
          else                  (tagged.mapLast(_ |+| tagToApply) :+ t1, (newSectionTags, previousTag))

        /** beginning of section from the previous fragment */
        case f => (tagged :+ (sectionTags.sumr |+| previousTag), (sectionTags, AlwaysWhenNoIncludeTag))
      }
    }
    tags
  }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy