Skip to content
This repository has been archived by the owner on Mar 25, 2020. It is now read-only.

Commit

Permalink
Fix some speclite coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
Alistair-Johnson committed Nov 1, 2015
1 parent c5b2143 commit 2986946
Show file tree
Hide file tree
Showing 10 changed files with 301 additions and 131 deletions.
7 changes: 5 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ lazy val checklite = prj(checkliteM)
lazy val checkliteJVM = checkliteM.jvm
lazy val checkliteJS = checkliteM.js
lazy val checkliteM = module("checklite", CrossType.Pure)
.dependsOn(testkitM % "compile; test -> test", lawkitM % "compile; test -> test")
.dependsOn(testkitM % "compile; test -> test", lawkitM % "compile; test -> test", specbaseM % "compile; test -> test")
.settings(disciplineDependencies:_*)
.settings(addLibs(vAll, "scalacheck"):_*)
.jvmSettings(libraryDependencies += "org.scala-sbt" % "test-interface" % "1.0")
Expand Down Expand Up @@ -184,4 +184,7 @@ lazy val disciplineDependencies = Seq(addLibs(vAll, "discipline", "scalacheck" )

lazy val publishSettings = sharedPublishSettings(gh, devs) ++ credentialSettings ++ sharedReleaseProcess

lazy val scoverageSettings = sharedScoverageSettings(60)
import scoverage.ScoverageSbtPlugin._
lazy val scoverageSettings = sharedScoverageSettings(60) ++ Seq(
ScoverageKeys.coverageExcludedPackages := "catalysts\\.Platform"
)
95 changes: 9 additions & 86 deletions checklite/src/main/scala/catalysts/checklite/CheckLite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.scalacheck
import org.scalacheck.{Arbitrary, Gen, Prop, Properties, Shrink}

import catalysts.macros.ClassInfo._
import catalysts.specbase.SpecBase
import catalysts.testkit.{Equal, Show}
import reflect.ClassTag
import scala.scalajs.js.annotation.JSExportDescendentClasses
Expand All @@ -29,7 +30,7 @@ class PropertyOpsWithProp(propName: String, prop: Prop, name:String, props: Prop
property(propName) = prop
}

abstract class CheckLite extends Properties("") {
abstract class CheckLite extends Properties("") with SpecBase[Prop, Properties]{

override val name:String = className(this)

Expand All @@ -51,108 +52,29 @@ abstract class CheckLite extends Properties("") {
} */
}

private var context: String = ""

def check(x: => Boolean): Prop = x must_== true

def fail(msg: String): Nothing = throw new AssertionError(msg)

implicit class StringOps2(s: String) {

def should[A](a: => Any): Unit = {
val saved = context
context = s
try {
val r = a
} finally {
context = saved
}
}

/*
def ![A](a: => A)(implicit ev: (A) => Prop): Unit = in(a)
/* def in[A](a: => A)(implicit ev: (A) => Prop): Unit = property(context + ":" + s) = new Prop {
def apply(prms: Parameters): Result = {
try ev(a).apply(prms) catch {
case e: Throwable => Result(status = Exception(e))
}
} // TODO sort out the laziness / implicit conversions properly
}
*/
def in[A](a: => A)(implicit ev: (A) => Prop): Unit = property(context + ":" + s) = new InStringOps(a)
*/
def ![A](a: => A)(implicit ev: (=> A) => Prop): Unit = in(a)
implicit class CheckLiteStringOps(s: String) extends SpecBaseStringOps(s){

def in[A](a: => A)(implicit ev: (=> A) => Prop): Unit = {
property(context + ":" + s) = new InStringOps(a)
()
}

}
implicit def booleanToProp(b: => Boolean): Prop = Prop.secure(b)

implicit class AnyOps2[A](actual: => A) {

def must_===(expected: A)(implicit s: Show[A], e: Equal[A]): Unit = {
val act = actual
def test = e.eqv(expected, act)
def koMessage = "%s !== %s".format(s.show(act), s.show(expected))

if (!test)
fail(koMessage)
}

def must_==(expected: A): Unit = {
val act = actual
def test = expected == act
def koMessage = "%s !== %s".format(act, expected)
if (!test)
fail(koMessage)
}

def mustMatch(f: PartialFunction[A, Boolean]): Unit = {
val act = actual
def test = f.isDefinedAt(act) && f(act)
def koMessage = "%s does not satisfy partial function".format(act)
if (!test)
fail(koMessage)
}

def and[B](b: => B): B = {
actual
b
}

def mustBe_<(x: Int)(implicit ev: A <:< Int) = {
val act = actual
def test = ev(act) < x
def koMessage = "%s <! %s".format(actual, x)
if (!test)
fail(koMessage)
}

def mustThrowA[T <: Throwable](implicit man: ClassTag[T]): Unit = {
val erasedClass = man.runtimeClass
val failed:Boolean =
try {
actual
true
} catch {
case ex: Throwable =>
if (!erasedClass.isInstance(ex))
fail("wrong exception thrown, expected: " + erasedClass + " got: " + ex)
else false
}
if (failed) fail("no exception thrown, expected " + erasedClass)
}
}

/*
def prop[T, R](result: T => R)(implicit toProp: (=>R) => Prop, a: Arbitrary[T], s: Shrink[T]): Prop = check1(result)
implicit def propToProp(p: => Prop): Prop = p
implicit def check1[T, R](result: T => R)(implicit toProp: (=>R) => Prop, a: Arbitrary[T], s: Shrink[T]): Prop = Prop.forAll((t: T) => toProp(result(t)))
implicit def anyToProp(u: => Any): Prop = booleanToProp({u; true})
implicit def unitToProp(u: => Unit): Prop = booleanToProp({u; true})
implicit def unitToProp2(u: Unit): Prop = booleanToProp(true)
implicit def booleanToProp(b: => Boolean): Prop = Prop.secure(b)
/**
* Most of our scalacheck tests use (Int => Int). This generator includes non-constant
Expand All @@ -164,4 +86,5 @@ abstract class CheckLite extends Properties("") {
(1, Gen.const((x: Int) => x + 1)),
(3, A.arbitrary.map(a => (_: Int) => a))
))
*/
}
32 changes: 32 additions & 0 deletions checklite/src/test/scala/catalysts/checklite/AllTests.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,42 @@
package catalysts
package checklite

import catalysts.specbase.SpecBaseTests
import catalysts.testkit._


import org.scalacheck.{Prop, Properties}

class CheckliteSpecBaseTests extends Suite with SpecBaseTests[Prop, Properties]

//import catalysts.lawkit.{LawSpecTests, LawTests}
//class ScalatestLawTests extends Suite with LawTests
//class ScalatestLawSpecTests extends Suite with LawSpecTests

class CheckliteFSpecTests extends Suite with FSpecTests
class CheckliteFSuiteTests extends Suite with FSuiteTests
class CheckliteJUnitTests extends Suite with JUnitTests
class CheckliteTestSpecTests extends Suite with TestSpecTests
class ChecklitetWSpecTests extends Suite with WSpecTests


object MyProps extends Properties("MyProps") {
property("myProp1") = Prop.forAll { (l1: List[Int], l2: List[Int]) =>
l1.size + l2.size == (l1 ::: l2).size
}
}

class CheckliteCoreTests extends Suite {

//testing error condition
val i = new InStringOps(null).apply(null)

val p = Prop.forAll { (l1: List[Int], l2: List[Int]) =>
l1.size + l2.size == (l1 ::: l2).size }

checkAll(MyProps)

val p2 = MyProps withProp ("myProp2", p)

checkAll("myProp3", p2)
}
2 changes: 1 addition & 1 deletion platform/jvm/src/main/scala/catalysts/Platform_jvm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package catalysts

object Platform {
// using `final val` makes compiler constant-fold any use of these values, dropping dead code automatically
// $COVERAGE-OFF$Final vals not checked
// $COVERAGE-OFF$
final val isJvm = true
final val isJs = false
// $COVERAGE-ON$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ trait SpecBaseTests[P,PS] extends SpecBase[P,PS] {

1 mustBe_< 2

(2 mustBe_< 2).mustThrowA[AssertionError]

val fTrue: PartialFunction[Boolean, Boolean] = { case b => b == true }
val fFalse: PartialFunction[Int, Boolean] = { case x => false }

Expand All @@ -20,4 +22,6 @@ trait SpecBaseTests[P,PS] extends SpecBase[P,PS] {
this mustBeTheSameAs this

(List(false) mustBeTheSameAs List(true)).mustThrowA[AssertionError]


}
47 changes: 25 additions & 22 deletions speclite/src/main/scala/speclite/Pretty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import Prop.Arg
sealed trait Pretty extends Serializable {
def apply(prms: Pretty.Params): String

def map(f: String => String) = Pretty(prms => f(Pretty.this(prms)))
// def map(f: String => String) = Pretty(prms => f(Pretty.this(prms)))

def flatMap(f: String => Pretty) = Pretty(prms => f(Pretty.this(prms))(prms))
// def flatMap(f: String => Pretty) = Pretty(prms => f(Pretty.this(prms))(prms))
}

object Pretty {
Expand All @@ -31,6 +31,7 @@ object Pretty {
def /(s2: String) = if(s2 == "") s1 else s1+"\n"+s2
}

/*
def pad(s: String, c: Char, length: Int) =
if(s.length >= length) s
else s + List.fill(length-s.length)(c).mkString
Expand Down Expand Up @@ -59,11 +60,11 @@ object Pretty {
loop(0)
builder.result()
}

*/
implicit def prettyAny(t: Any) = Pretty { p => t.toString }

implicit def prettyString(t: String) = Pretty { p => "\""++escapeControlChars(t)++"\"" }

// implicit def prettyString(t: String) = Pretty { p => "\""++escapeControlChars(t)++"\"" }
/*
implicit def prettyList(l: List[Any]) = Pretty { p =>
l.map("\""+_+"\"").mkString("List(", ", ", ")")
}
Expand All @@ -81,7 +82,7 @@ object Pretty {
e.getClass.getName + ": " + e.getMessage / strs2.mkString("\n")
}

*/
def prettyArgs(args: Seq[Arg[Any]]): Pretty = Pretty { prms =>
if(args.isEmpty) "" else {
for((a,i) <- args.zipWithIndex) yield {
Expand All @@ -94,24 +95,26 @@ object Pretty {
}.mkString("\n")
}

implicit def prettyTestRes(res: SpecLiteTest.Result) = Pretty { prms =>
def labels(ls: collection.immutable.Set[String]) =
if(ls.isEmpty) ""
else "> Labels of failing property: " / ls.mkString("\n")
val s = res.status match {
case SpecLiteTest.Proved(args) => "" //"OK, proved property."/prettyArgs(args)(prms)
case SpecLiteTest.Passed => "OK, passed "+res.succeeded+" tests."
case SpecLiteTest.Failed(args, l) =>
"Falsified after "+res.succeeded+" passed tests."/labels(l)/prettyArgs(args)(prms)
case SpecLiteTest.Exhausted =>
"Gave up after only "+res.succeeded+" passed tests. " +
res.discarded+" tests were discarded."
case SpecLiteTest.PropException(args,e,l) => s"failed: ${e.getMessage}"
//"Exception raised on property evaluation."/labels(l)/prettyArgs(args)(prms)/
implicit def prettyTestRes(res: SpecLiteTest.Result) = {
Pretty { prms =>
def labels(ls: collection.immutable.Set[String]) =
if(ls.isEmpty) ""
else "> Labels of failing property: " / ls.mkString("\n")
val s = res.status match {
case SpecLiteTest.Proved(args) => "" //"OK, proved property."/prettyArgs(args)(prms)
case SpecLiteTest.Passed => "OK, passed "+res.succeeded+" tests."
case SpecLiteTest.Failed(args, l) =>
"Falsified after "+res.succeeded+" passed tests."/labels(l)/prettyArgs(args)(prms)
case SpecLiteTest.Exhausted =>
"Gave up after only "+res.succeeded+" passed tests. " +
res.discarded+" tests were discarded."
case SpecLiteTest.PropException(args,e,l) => s"failed: ${e.getMessage}"
//"Exception raised on property evaluation."/labels(l)/prettyArgs(args)(prms)/
//RED + "> Exception: " + e.getMessage // pretty(e,prms)
}
val t = if(prms.verbosity <= 1) "" else "Elapsed time: "+prettyTime(res.time)
s/t //pretty(res.freqMap,prms)
}
val t = if(prms.verbosity <= 1) "" else "Elapsed time: "+prettyTime(res.time)
s/t //pretty(res.freqMap,prms)
}

def prettyTime(millis: Long): String = {
Expand Down
21 changes: 11 additions & 10 deletions speclite/src/main/scala/speclite/Prop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ class Properties(val name: String) extends Prop {

/** Returns one property which holds if and only if all of the
* properties in this property collection hold */
private def oneProperty: Prop = Prop.all((properties map (_._2)):_*)
private def oneProperty: Prop = Prop.all((properties map (_._2)):_*)

/** Returns all properties of this collection in a list of name/property
* pairs. */
def properties: Seq[(String,Prop)] = props

def apply(p: Gen.Parameters) = oneProperty(p)
def apply(p: Gen.Parameters) = oneProperty(p)

class PropertySpecifier() {
def update(propName: String, p: Prop) = props += ((name+"."+propName, p))
Expand All @@ -35,21 +35,21 @@ class PropFromFun(f: Gen.Parameters => Prop.Result) extends Prop {
@scala.scalajs.js.annotation.JSExportDescendentObjects
trait Prop {

import Prop.{Result, secure}
import Prop.{Result}//, secure}
import Gen.Parameters

def apply(prms: Parameters): Result
def apply(prms: Parameters): Result

def map(f: Result => Result): Prop = Prop(prms => f(this(prms)))
// def map(f: Result => Result): Prop = Prop(prms => f(this(prms)))

def flatMap(f: Result => Prop): Prop = Prop(prms => f(this(prms))(prms))
// def flatMap(f: Result => Prop): Prop = Prop(prms => f(this(prms))(prms))

def combine(p: Prop)(f: (Result, Result) => Result) =
for(r1 <- this; r2 <- p) yield f(r1,r2)
// def combine(p: Prop)(f: (Result, Result) => Result) =
// for(r1 <- this; r2 <- p) yield f(r1,r2)

def &&(p: => Prop) = combine(secure(p))(_ && _)
// def &&(p: => Prop) = combine(secure(p))(_ && _)

override def toString = "Prop"
// override def toString = "Prop"
}

object Prop {
Expand Down Expand Up @@ -109,6 +109,7 @@ object Prop {
if(ps.isEmpty) proved
else Prop(prms => ps.map(p => p(prms)).reduceLeft(_ && _)
)

def exception(e: Throwable): Prop = Prop(Result(status = Exception(e)))

def secure[P](p: => P)(implicit ev: P => Prop): Prop =
Expand Down
8 changes: 4 additions & 4 deletions speclite/src/main/scala/speclite/SpecLiteFramework.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ private abstract class SpecLiteRunner(
def execute(handler: EventHandler, loggers: Array[Logger],
continuation: Array[Task] => Unit
): Unit = continuation(execute(handler,loggers))

}

def rootTask(td: TaskDef) = new BaseTask(td) {
Expand Down Expand Up @@ -167,15 +168,14 @@ final class SpecLiteFramework extends Framework {
s"$heading: Total $testCount, Failed $failureCount, Errors $errorCount, Passed $successCount"
}
}

def slaveRunner(args: Array[String], remoteArgs: Array[String],
loader: ClassLoader, send: String => Unit): Runner =
loader: ClassLoader, send: String => Unit): Runner =
new SpecLiteRunner(args, remoteArgs, loader) {
def receiveMessage(msg: String) = None

def done = {
send(s"d$testCount,$successCount,$failureCount,$errorCount")
""
""
}
}
}
}
Loading

0 comments on commit 2986946

Please sign in to comment.