Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ lazy val scalacheck = (project in file("."))
Resolver.sonatypeRepo("releases")
),
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "2.2.4",
"org.scala-exercises" %% "exercise-compiler" % version.value,
"org.scala-exercises" %% "definitions" % version.value,
"org.scalacheck" %% "scalacheck" % "1.12.5",
"com.github.alexarchambault" %% "scalacheck-shapeless_1.12" % "0.3.1",
"org.scalatest" %% "scalatest" % "3.0.1" exclude("org.scalacheck", "scalacheck"),
"org.scala-exercises" %% "exercise-compiler" % version.value excludeAll ExclusionRule("com.github.alexarchambault"),
"org.scala-exercises" %% "definitions" % version.value excludeAll ExclusionRule("com.github.alexarchambault"),
"com.fortysevendeg" %% "scalacheck-datetime" % "0.2.0",
"com.github.alexarchambault" %% "scalacheck-shapeless_1.13" % "1.1.3",
compilerPlugin("org.spire-math" %% "kind-projector" % "0.9.0")
)
)
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/scalachecklib/ArbitrarySection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package scalachecklib
import org.scalatest.Matchers
import org.scalatest.prop.Checkers

/** ==The `arbitrary` Generator
/** ==The `arbitrary` Generator==
*
* There is a special generator, `org.scalacheck.Arbitrary.arbitrary`, which generates arbitrary values of any
* supported type.
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/scalachecklib/PropertiesSection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ object PropertiesSection extends Checkers with Matchers with org.scalaexercises.
*
*/
def groupingProperties(res0: Int, res1: Int, res2: Int) = {
import org.scalacheck.Properties
import org.scalacheck.{Prop, Properties}

class ZeroSpecification extends Properties("Zero") {

Expand All @@ -199,6 +199,6 @@ object PropertiesSection extends Checkers with Matchers with org.scalaexercises.

}

check(new ZeroSpecification)
check(Prop.all(new ZeroSpecification().properties.map(_._2): _*))
}
}
153 changes: 153 additions & 0 deletions src/main/scala/scalachecklib/ScalacheckDatetimeSection.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package scalachecklib

import org.scalatest.Matchers
import org.scalatest.prop.Checkers

/** scalacheck-datetime is a library for helping use datetime libraries with ScalaCheck
*
* The motivation behind this library is to provide a simple, easy way to provide generated date and time instances
* that are useful to your own domain.
*
* For SBT, you can add the dependency to your project’s build file:
*
* {{{
* resolvers += Resolver.sonatypeRepo("releases")
*
* "com.fortysevendeg" %% "scalacheck-datetime" % "0.2.0" % "test"
* }}}
*
* Please, visit the [[https://47deg.github.io/scalacheck-datetime homepage]] for more information
*
* @param name scalacheck-datetime
*/
object ScalacheckDatetimeSection extends Checkers with Matchers with org.scalaexercises.definitions.Section {

/** ==Usage==
*
* To arbitrarily generate dates and times, you need to have the `Arbitrary` in scope for your date/time class.
* Assuming Joda Time:
*/
def usage(res0: Boolean) = {

import com.fortysevendeg.scalacheck.datetime.joda.ArbitraryJoda._
import org.joda.time.DateTime
import org.scalacheck.Prop.forAll

check {
forAll { dt: DateTime =>
(dt.getDayOfMonth >= 1 && dt.getDayOfMonth <= 31) == res0
}
}
}

/** ==A note on imports==
*
* For all of the examples given in this document, you can substitute `jdk8` for `joda` and vice-versa,
* depending on which library you would like to generate instances for.
*
* ==Implementation==
*
* The infrastructure behind the generation of date/time instances for any given date/time library,
* which may take ranges into account, is done using a fairly simple typeclass, which has the type signature
* `ScalaCheckDateTimeInfra[D, R]`. That is to say, as long as there is an implicit `ScalaCheckDateTimeInfra`
* instance in scope for a given date/time type `D` (such as Joda’s `DateTime`) and a range type `R`
* (such as Joda’s `Period`), then the code will compile and be able to provide generated date/time instances.
*
* As stated, currently there are two instances, `ScalaCheckDateTimeInfra[DateTime, Period]` for Joda Time and
* `ScalaCheckDateTimeInfra[ZonedDateTime, Duration]` for Java SE 8’s Date and Time.
*
* ==Granularity==
*
* If you wish to restrict the precision of the generated instances, this library refers to that as <i>granularity</i>.
*
* You can constrain the granularity to:
*
* <ul>
* <li>Seconds</li>
* <li>Minutes</li>
* <li>Hours</li>
* <li>Days</li>
* <li>Years</li>
* </ul>
*
* When a value is constrained, the time fields are set to zero, and the rest to the first day of the month,
* or day of the year. For example, if you constrain a field to be years, the generated instance will be midnight
* exactly, on the first day of January.
*
* To constrain a generated type, you simply need to provide an import for the typeclass for your date/time and
* range, and also an import for the granularity. As an example, this time using Java SE 8's `java.time` package:
*/
def granularity(res0: Int, res1: Int, res2: Int, res3: Int, res4: Int) = {

import java.time._
import com.fortysevendeg.scalacheck.datetime.jdk8.ArbitraryJdk8._
import com.fortysevendeg.scalacheck.datetime.jdk8.granularity.years
import org.scalacheck.Prop.forAll

check {
forAll { zdt: ZonedDateTime =>
zdt.getMonth == Month.JANUARY
(zdt.getDayOfMonth == res0) &&
(zdt.getHour == res1) &&
(zdt.getMinute == res2) &&
(zdt.getSecond == res3) &&
(zdt.getNano == res4)
}
}

}

/** ==Creating Ranges==
*
* You can generate date/time instances only within a certain range, using the `genDateTimeWithinRange` in the
* `GenDateTime` class. The function takes two parameters, the date/time instances as a base from which to generate
* new date/time instances, and a range for the generated instances.
*
* If the range is positive, it will be in the future from the base date/time, negative in the past.
*
* Showing this usage with Joda Time:
*/
def ranges(res0: Int) = {

import org.joda.time._
import com.fortysevendeg.scalacheck.datetime.instances.joda._
import com.fortysevendeg.scalacheck.datetime.GenDateTime.genDateTimeWithinRange
import org.scalacheck.Prop.forAll

val from = new DateTime(2016, 1, 1, 0, 0)
val range = Period.years(1)

check {
forAll(genDateTimeWithinRange(from, range)) { dt =>
dt.getYear == res0
}
}
}

/** ==Using Granularity and Ranges Together==
*
* As you would expect, it is possible to use the granularity and range concepts together.
* This example should not show anything surprising by now:
*/
def granularityAndRanges(res0: Int, res1: Int, res2: Int, res3: Int, res4: Int) = {

import org.joda.time._
import com.fortysevendeg.scalacheck.datetime.instances.joda._
import com.fortysevendeg.scalacheck.datetime.GenDateTime.genDateTimeWithinRange
import com.fortysevendeg.scalacheck.datetime.joda.granularity.days
import org.scalacheck.Prop.forAll

val from = new DateTime(2016, 1, 1, 0, 0)
val range = Period.years(1)

check {
forAll(genDateTimeWithinRange(from, range)) { dt =>
(dt.getYear == res0) &&
(dt.getHourOfDay == res1) &&
(dt.getMinuteOfHour == res2) &&
(dt.getSecondOfMinute == res3) &&
(dt.getMillisOfSecond == res4)
}
}
}
}
3 changes: 2 additions & 1 deletion src/main/scala/scalachecklib/ScalacheckLibrary.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ object ScalacheckLibrary extends org.scalaexercises.definitions.Library {

override def sections = List(
PropertiesSection,
GeneratorsSection
GeneratorsSection,
ScalacheckDatetimeSection
)

override def logoPath = "scalacheck"
Expand Down
11 changes: 5 additions & 6 deletions src/test/scala/scalachecklib/ArbitrarySpec.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package scalachecklib

import org.scalacheck.Shapeless._
import org.scalaexercises.Test
import org.scalatest.Spec
import org.scalatest.FunSuite
import org.scalatest.prop.Checkers
import shapeless.HNil

class ArbitrarySpec extends Spec with Checkers {
class ArbitrarySpec extends FunSuite with Checkers {

def `implicit arbitrary char` = {
test("implicit arbitrary char") {

check(
Test.testSuccess(
Expand All @@ -18,7 +17,7 @@ class ArbitrarySpec extends Spec with Checkers {
)
}

def `implicit arbitrary case class` = {
test("implicit arbitrary case class") {

check(
Test.testSuccess(
Expand All @@ -28,7 +27,7 @@ class ArbitrarySpec extends Spec with Checkers {
)
}

def `arbitrary on gen` = {
test("arbitrary on gen") {

check(
Test.testSuccess(
Expand Down
19 changes: 9 additions & 10 deletions src/test/scala/scalachecklib/GeneratorsSpec.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package scalachecklib

import org.scalacheck.Shapeless._
import org.scalaexercises.Test
import org.scalatest.Spec
import org.scalatest.FunSuite
import org.scalatest.prop.Checkers
import shapeless.HNil

class GeneratorsSpec extends Spec with Checkers {
class GeneratorsSpec extends FunSuite with Checkers {

def `for-comprehension generator` = {
test("for-comprehension generator") {

check(
Test.testSuccess(
Expand All @@ -19,7 +18,7 @@ class GeneratorsSpec extends Spec with Checkers {

}

def `oneOf method` = {
test("oneOf method") {

check(
Test.testSuccess(
Expand All @@ -30,7 +29,7 @@ class GeneratorsSpec extends Spec with Checkers {

}

def `alphaChar, posNum and listOfN` = {
test("alphaChar, posNum and listOfN") {

check(
Test.testSuccess(
Expand All @@ -41,7 +40,7 @@ class GeneratorsSpec extends Spec with Checkers {

}

def `suchThat condition` = {
test("suchThat condition") {

check(
Test.testSuccess(
Expand All @@ -52,7 +51,7 @@ class GeneratorsSpec extends Spec with Checkers {

}

def `case class generator` = {
test("case class generator") {

check(
Test.testSuccess(
Expand All @@ -63,7 +62,7 @@ class GeneratorsSpec extends Spec with Checkers {

}

def `sized generator` = {
test("sized generator") {

check(
Test.testSuccess(
Expand All @@ -74,7 +73,7 @@ class GeneratorsSpec extends Spec with Checkers {

}

def `list container` = {
test("list container") {

check(
Test.testSuccess(
Expand Down
16 changes: 7 additions & 9 deletions src/test/scala/scalachecklib/PropertiesSpec.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package scalachecklib

import org.scalacheck.Shapeless._
import org.scalaexercises.Test
import org.scalatest.Spec
import org.scalatest.FunSuite
import org.scalatest.prop.Checkers
import shapeless.HNil

class PropertiesSpec extends FunSuite with Checkers {

class PropertiesSpec extends Spec with Checkers {

def `always ends with the second string` = {
test("always ends with the second string") {

check(
Test.testSuccess(
Expand All @@ -19,7 +17,7 @@ class PropertiesSpec extends Spec with Checkers {
)
}

def `all numbers are generated between the desired interval` = {
test("all numbers are generated between the desired interval") {

check(
Test.testSuccess(
Expand All @@ -29,7 +27,7 @@ class PropertiesSpec extends Spec with Checkers {
)
}

def `all generated numbers are even` = {
test("all generated numbers are even") {

check(
Test.testSuccess(
Expand All @@ -39,7 +37,7 @@ class PropertiesSpec extends Spec with Checkers {
)
}

def `only the second condition is true` = {
test("only the second condition is true") {

check(
Test.testSuccess(
Expand All @@ -49,7 +47,7 @@ class PropertiesSpec extends Spec with Checkers {
)
}

def `the zero specification only works for 0` = {
test("the zero specification only works for 0") {

check(
Test.testSuccess(
Expand Down
Loading