<commit_before>package io.bazel.rulesscala.specs2

import io.bazel.rulesscala.test_discovery.FilteredRunnerBuilder.FilteringRunnerBuilder
import io.bazel.rulesscala.test_discovery._
import org.junit.runner.notification.RunNotifier
import org.junit.runner.{Description, RunWith, Runner}
import org.junit.runners.Suite
import org.junit.runners.model.RunnerBuilder
import org.specs2.concurrent.ExecutionEnv
import org.specs2.control.Action
import org.specs2.fp.Tree.Node
import org.specs2.fp.{Tree, TreeLoc}
import org.specs2.main.{Arguments, CommandLine, Select}
import org.specs2.specification.core.{Env, Fragment, SpecStructure}
import org.specs2.specification.process.Stats

import java.util
import java.util.regex.Pattern
import scala.collection.JavaConverters._
import scala.collection.immutable.Iterable
import scala.language.reflectiveCalls
import scala.util.Try
import scala.util.control.NonFatal

@RunWith(classOf[Specs2PrefixSuffixTestDiscoveringSuite])
class Specs2DiscoveredTestSuite

object FilteringBuilder {
  def apply(): FilteringRunnerBuilder  =
    Specs2FilteringRunnerBuilder.f orElse JUnitFilteringRunnerBuilder.f
}

class Specs2PrefixSuffixTestDiscoveringSuite(suite: Class[Any], runnerBuilder: RunnerBuilder)
  extends Suite(
    new FilteredRunnerBuilder(runnerBuilder, FilteringBuilder()),
    PrefixSuffixTestDiscoveringSuite.discoverClasses()) {

  override def getName: String = "Aggregate Specs2 Test Suite"

  override def getChildren: util.List[Runner] =
    super.getChildren.asScala
      .collect {
        case r: FilteredSpecs2ClassRunner if r.matchesFilter => Some(r)
        case _: FilteredSpecs2ClassRunner => None
        case other => Some(other)
      }.flatten.asJava
}

object Specs2FilteringRunnerBuilder {
  val f: FilteringRunnerBuilder = {
    case (_: org.specs2.runner.JUnitRunner, testClass: Class[_], pattern: Pattern) =>
      new FilteredSpecs2ClassRunner(testClass, pattern)
  }
}

class FilteredSpecs2ClassRunner(testClass: Class[_], testFilter: Pattern)
  extends org.specs2.runner.JUnitRunner(testClass) {

  override def getDescription(env: Env): Description = {
    try createFilteredDescription(specStructure, env.specs2ExecutionEnv)
    catch { case NonFatal(t) => env.shutdown; throw t; }
  }

  private def createFilteredDescription(specStructure: SpecStructure, ee: ExecutionEnv): Description = {
    val descTree = createDescriptionTree(ee).map(_._2)

    def bottomUp[A, B](t: Tree[A], f: ((A, Iterable[B]) => B)): Tree[B] = {
      val tbs = t.subForest.map(t => bottomUp(t, f))
      Node(f(t.rootLabel, tbs.map(_.rootLabel)), tbs)
    }

    bottomUp(descTree.toTree, {
      (description: Description, children: Iterable[Description]) =><commit_msg>use composition in runner to avoid double lazy initialization when ru… (#1336)<commit_after>package io.bazel.rulesscala.specs2

import io.bazel.rulesscala.test_discovery.FilteredRunnerBuilder.FilteringRunnerBuilder
import io.bazel.rulesscala.test_discovery._
import org.junit.runner.notification.RunNotifier
import org.junit.runner.{Description, RunWith, Runner}
import org.junit.runners.Suite
import org.junit.runners.model.RunnerBuilder
import org.specs2.concurrent.ExecutionEnv
import org.specs2.control.Action
import org.specs2.fp.Tree.Node
import org.specs2.fp.{Tree, TreeLoc}
import org.specs2.main.{Arguments, CommandLine, Select}
import org.specs2.specification.core.{Env, Fragment, SpecStructure, SpecificationStructure}
import org.specs2.specification.process.Stats

import java.util
import java.util.regex.Pattern
import scala.collection.JavaConverters._
import scala.collection.immutable.Iterable
import scala.language.reflectiveCalls
import scala.util.Try
import scala.util.control.NonFatal

@RunWith(classOf[Specs2PrefixSuffixTestDiscoveringSuite])
class Specs2DiscoveredTestSuite

object FilteringBuilder {
  def apply(): FilteringRunnerBuilder  =
    Specs2FilteringRunnerBuilder.f orElse JUnitFilteringRunnerBuilder.f
}

class Specs2PrefixSuffixTestDiscoveringSuite(suite: Class[Any], runnerBuilder: RunnerBuilder)
  extends Suite(
    new FilteredRunnerBuilder(runnerBuilder, FilteringBuilder()),
    PrefixSuffixTestDiscoveringSuite.discoverClasses()) {

  override def getName: String = "Aggregate Specs2 Test Suite"

  override def getChildren: util.List[Runner] =
    super.getChildren.asScala
      .collect {
        case r: FilteredSpecs2ClassRunner if r.matchesFilter => Some(r)
        case _: FilteredSpecs2ClassRunner => None
        case other => Some(other)
      }.flatten.asJava
}

object Specs2FilteringRunnerBuilder {
  val f: FilteringRunnerBuilder = {
    case (parentRunner: org.specs2.runner.JUnitRunner, testClass: Class[_], pattern: Pattern) =>
      new FilteredSpecs2ClassRunner(parentRunner, testClass, pattern)
  }
}

class FilteredSpecs2ClassRunner(parentRunner: org.specs2.runner.JUnitRunner, testClass: Class[_], testFilter: Pattern)
  extends org.specs2.runner.JUnitRunner(testClass) {

  //taking it from parent so not to initialize test classes multiple times
  override lazy val specification: SpecificationStructure = parentRunner.specification

  override def getDescription(env: Env): Description = {
    try createFilteredDescription(specStructure, env.specs2ExecutionEnv)
    catch { case NonFatal(t) => env.shutdown; throw t; }
  }

  private def createFilteredDescription(specStructure: SpecStructure, ee: ExecutionEnv): Description = {
    val descTree = createDescriptionTree(ee).map(_._2)

    def bottomUp[A, B](t: Tree[A], f: ((A, Iterable[B]) => B)): Tree[B] = {
      val tbs = t.subForest.map(t => bottomUp(t, f))
      Node(f(t.rootLabel, tbs.map(_.rootLabel)), tbs)
    }

    bottomUp(descTree.toTree, {
      (description: Description, children: Iterable[Description]) =>
{'fraction_non_alphanumeric': 0.09892398472752517, 'fraction_numerical': 0.008503991669559181, 'mean_word_length': 5.332967032967033, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '2141471', 'n_tokens_mistral': 1815, 'n_tokens_neox': 1781, 'n_words': 364}