Skip to content
Browse files

added infrastruture for running grouped tests.

  • Loading branch information...
1 parent 50380ba commit 57fcb8ff15f5fc3f4e1bcc8800e49d083140ec0b @rssh committed
View
4 src/main/scala/org/scalatest/managedfixture/FeatureSpec.scala
@@ -108,7 +108,9 @@ trait FeatureSpec[T <: FixtureStateTypes] extends fixture.Suite
**/
def fixtureStateTypes: T
- protected override lazy val internalSpec = new InternalFeatureSpec[T](this);
+
+ protected override lazy val internalSpec: InternalFeatureSpec[T] = new InternalFeatureSpec[T](this);
+
override def withFixture(test: OneArgTest): Unit =
throw new IllegalStateException("You can't call withFixture diretly in managedfixture");
View
17 src/main/scala/org/scalatest/managedfixture/FlatSpec.scala
@@ -202,7 +202,17 @@ trait FlatSpec[T <: FixtureStateTypes] extends Suite with ShouldVerb with MustVe
// here we recreate internal suite and will be pass to one all 'real' functionality.
- private[scalatest] lazy val internalSpec = new InternalFlatSpec(this);
+ private[scalatest] lazy val internalSpec: InternalFlatSpec[T] =
+ if (this.isInstanceOf[Grouped]) {
+ if (GroupSpecConstructorKluge.currentOwner!=None) {
+ GroupSpecConstructorKluge.currentOwner.value.get.asInstanceOf[FlatSpecGroup[T]].internalSpec;
+ } else {
+ // it was called outside group, create internal constructor
+ new InternalFlatSpec(this);
+ }
+ } else {
+ new InternalFlatSpec(this);
+ }
implicit protected def info: Informer = internalSpec._info;
@@ -380,10 +390,15 @@ trait FlatSpec[T <: FixtureStateTypes] extends Suite with ShouldVerb with MustVe
override def run(testName: Option[String], reporter: Reporter, stopper: Stopper, filter: Filter,
configMap: Map[String, Any], distributor: Option[Distributor], tracker: Tracker) {
+ if (isGrouped) {
+ this.asInstanceOf[Grouped].checkGroupExists( classOf[FlatSpecGroup[_]] );
+ }
internalSpec.run(testName, reporter, stopper, filter, configMap, distributor, tracker);
}
protected val behave = new BehaveWord
+
+ private def isGrouped: Boolean = this.isInstanceOf[Grouped];
}
private[scalatest] object FlatSpecConstructorKluge
View
21 src/main/scala/org/scalatest/managedfixture/FlatSpecGroup.scala
@@ -0,0 +1,21 @@
+package org.scalatest.managedfixture
+
+
+import scala.util.DynamicVariable
+import org.scalatest._
+import ua.gradsoft.managedfixture._
+
+
+abstract class FlatSpecGroup[T <: FixtureStateTypes] extends FlatSpec[T]
+ with SpecGroup
+{
+
+ override def run(testName: Option[String], reporter: Reporter, stopper: Stopper, filter: Filter,
+ configMap: Map[String, Any], distributor: Option[Distributor], tracker: Tracker) {
+ collectGrouped(classOf[FlatSpec[T]]);
+ internalSpec.run(testName, reporter, stopper, filter, configMap, distributor, tracker);
+ }
+
+}
+
+
View
35 src/main/scala/org/scalatest/managedfixture/Grouped.scala
@@ -0,0 +1,35 @@
+package org.scalatest.managedfixture
+
+import ua.gradsoft.managedfixture._
+
+trait Grouped {
+
+
+
+ /**
+ * check - are we have instance of clazz somewhere in our package structure
+ * upper to current class.
+ * [todo - check same fixture state types (?)]
+ */
+ def checkGroupExists(clazz:Class[_]):Boolean =
+ {
+ val pkg = clazz.getPackage();
+ val components = pkg.getName().split('.');
+ if (components.length > 1) {
+ var i=components.length;
+ var isFound = false;
+ while( i > 0 && !isFound ) {
+ isFound = ! ( ReflectionUtils.findClasses(components.take(i).mkString("."),
+ { (x: Class[_]) =>
+ !(classOf[FlatSpecGroup[_]].isAssignableFrom(x))
+ }, false) );
+ }
+ isFound;
+ }else{
+ false
+ }
+ }
+
+ def mark(owner:SpecGroup):Unit = {}
+
+}
View
39 src/main/scala/org/scalatest/managedfixture/SpecGroup.scala
@@ -0,0 +1,39 @@
+package org.scalatest.managedfixture
+
+import ua.gradsoft.managedfixture._
+import scala.util.DynamicVariable
+
+trait SpecGroup
+{
+
+ def checkClass[T](cl:Class[T]): Boolean
+ = true;
+
+ def checkObject(x:AnyRef): Boolean
+ = true;
+
+ private[scalatest] def collectGrouped[T](cl:Class[T]):Boolean =
+ {
+ ReflectionUtils.findClasses(this.getClass().getPackage().getName,
+ {
+ (x:Class[_]) =>
+ if (x.isInstanceOf[Grouped] && x.isInstanceOf[T]) {
+ if (checkClass(x)) {
+ GroupSpecConstructorKluge.currentOwner.withValue(Some(this)) {
+ val obj = x.newInstance().asInstanceOf[Grouped];
+ obj.mark(this);
+ }
+ }
+ }
+ true
+ },
+ true);
+ }
+
+
+}
+
+private[scalatest] object GroupSpecConstructorKluge
+{
+ val currentOwner = new DynamicVariable[Option[SpecGroup]](None);
+}
View
67 src/main/scala/ua/gradsoft/managedfixture/ReflectionUtils.scala
@@ -0,0 +1,67 @@
+package ua.gradsoft.managedfixture
+
+import java.io._
+import java.util.zip._
+
+/**
+ * helper class, which simplicify work with reflection
+ */
+object ReflectionUtils {
+
+
+ def findClasses(packageName:String, testFun: Class[_]=>Boolean, recursive:Boolean):Boolean =
+ {
+ val e = classLoader.getResources(packageName);
+ var more = true;
+ while(e.hasMoreElements && more) {
+ val url = e.nextElement();
+ more = forClassesInDir(packageName,url.getFile, testFun, recursive);
+ }
+ more
+ }
+
+ private[this] def forClassesInDir(pkgName:String, dir:String, fun: Class[_]=>Boolean, recursive: Boolean):Boolean =
+ {
+ var more = true;
+ if (dir.startsWith("file:") && dir.contains("!") ) {
+ val jar = new java.net.URL(dir.split("!")(0));
+ val zip = new ZipInputStream(jar.openStream());
+ var zipEntry = zip.getNextEntry;
+ while(zipEntry!=null && more) {
+ val className = zipEntry.getName.replaceAll("[$].*", "").replaceAll("[.]class","").replace('/', '.');
+ val c = Class.forName(className);
+ more = fun(c)
+ zipEntry = zip.getNextEntry;
+ }
+ } else {
+ var fd = new File(dir);
+ if (fd.exists) {
+ for(f <- fd.listFiles) {
+ var fname = f.getName;
+ if (fname.endsWith(".class")) {
+ val className = pkgName+"."+ fname.substring(0, fname.length-6);
+ val c = Class.forName(className);
+ more = fun(c);
+ } else if (f.isDirectory() && recursive) {
+ more = forClassesInDir(pkgName+"."+f.getName(),dir+"/"+f.getName,fun,recursive)
+ }
+ if (!more) {
+ return false;
+ }
+ }
+ }
+ }
+ more;
+ }
+
+ private[this] def classLoader: ClassLoader =
+ {
+ Option(Thread.currentThread().getContextClassLoader()) match {
+ case Some(x) => x
+ case None => this.getClass.getClassLoader();
+ }
+ }
+
+
+
+}

0 comments on commit 57fcb8f

Please sign in to comment.
Something went wrong with that request. Please try again.