I'm finding using specs2 with scalacheck to verify the Monoid laws a bit ugly when trying to make use of the scalaz scalacheck-binding library.
My code uses the scalaz Monoid so I wanted to use their laws to verify my MyType implements them.
This uglyness makes me think I'm missing something or mis-using Specs2 or scalacheck-binding API's. Sugestions apreciated.
This is what i've done:-
I'm using specs2 3.7 with scalaz 2.7.0
Reading the user guide at "http://etorreborre.github.io/specs2/guide/SPECS2-3.0/org.specs2.guide.UseScalaCheck.html"
I have extended my spec with the Scalacheck trait and I have an Arbitrary[MyType] in scope so I should be able to use scalacheck OK.
The doc mentioned above states that I need to pass a function to the prop method as long as the passed function returns a Result where scalacheck's Prop is a valid Result
The scalacheck-binding api gives me a monoid.laws[T] function that returns a Properties which is a Prop so this should be OK, it also takes implicit parameters of types Monoid[T], Equal[T] and Arbitrary[T] all of which I have in scope where T is MyType
I want to do this:
class MyTypeSpec extends Specification with ScalaCheck {
def is = s2"""
MyType spec must :-
obey the Monoid Laws $testMonoidLaws
"""
def testMonoidLaws = {
import org.scalacheck.{Gen, Arbitrary}
import scalaz.scalacheck.ScalazProperties._
implicit val arbMyType: Arbitrary[MyType] = genArbMyTpe() // an helper Arbitrary Gen func i have written
prop { monoid.laws[MyType] }
}
}
but prop cannot be applied to (org.scalacheck.Properties)
It requires the T in the Arbitrary to be the type in the parameter to the function, so I have done this, notice I trow away the parameter t, ...
class MyTypeSpec extends Specification with ScalaCheck {
def is = s2"""
MyType spec must :-
obey the Monoid Laws $testMonoidLaws
"""
def testMonoidLaws = {
import org.scalacheck.{Gen, Arbitrary}
import scalaz.scalacheck.ScalazProperties._
implicit val arbMyType: Arbitrary[MyType] = genArbMyTpe() //some Arbitrary Gen func
prop { (t: Path => monoid.laws[MyType] }
}
}
My test passes. yay! So What's the problem?
I'm uneasy about the test. All it says is it passed. I get no output like I would if using Scalacheck directly telling me which laws it ran and passed.
Also I throw away the parameter t and let monoid.laws[MyType] find the in scope implicits, which just seems wrong. Is it working? have I mangled the specs2 API?
modifying MyType so it would definatly fail the laws caused the test to fail, which is good but I am still uneasy as it always fails with
Falsified after 0 passed tests.
I can collect the Arbitrary[MyType] by doing
prop { (p: Path) => monoid.laws[Path] }.collectArg(f => "it was " + f.shows)
then running it like so
sbt testOnly MyTypeSpec -- scalacheck.verbose
which shows me the collected values of t when it works but as I throw away t I'm not sure if this is valid at all.
Is there a better way to test using Specs2 and the scalaz scalacheck-bindings that is less ugly and outputs info that give me confidence that Laws were tried and tested?
Thanks
Karl
You can use Properties directly without having to use prop. Here is a full example:
import org.specs2._
import scalaz.scalacheck.ScalazProperties._
import org.scalacheck._
import scalaz._, Scalaz._
import PositiveInt._
class TestSpec extends Specification with ScalaCheck { def is = s2"""
PositiveInt should pass the Monoid laws $e1
"""
def e1 = monoid.laws[PositiveInt]
}
case class PositiveInt(i: Int)
object PositiveInt {
implicit def ArbitraryPositiveInt: Arbitrary[PositiveInt] =
Arbitrary(Gen.choose(0, 100).map(PositiveInt.apply))
implicit def EqualPositiveInt: Equal[PositiveInt] =
Equal.equalA[PositiveInt]
implicit def MonoidPositiveInt: Monoid[PositiveInt] = new Monoid[PositiveInt] {
val zero = PositiveInt(1)
def append(p1: PositiveInt, p2: =>PositiveInt): PositiveInt =
PositiveInt(p1.i + p2.i)
}
}
And because the Monoid instance is incorrect it will fail with:
[info] TestSpec
[info]
[error] x PositiveInt should pass the Monoid laws
[error] Falsified after 0 passed tests.
[error] > Labels of failing property:
[error] monoid.left identity
[error] > ARG_0: PositiveInt(3)
[info]
[info]
[info] Total for specification TestSpec
[info] Finished in 185 ms
[info] 1 example, 1 failure, 0 error
The failure indicates the first laws that fails to pass. It doesn't however create several examples, one for each law, to display which law is being executed. If you want to do that you can map each property of the laws Properties to an example:
class TestSpec extends Specification with ScalaCheck { def is = s2"""
PositiveInt should pass the Monoid laws $properties
"""
def properties = toExamples(monoid.laws[PositiveInt])
def toExamples(ps: Properties): Fragments =
t ^ Fragments.foreach(ps.properties) { case (name, prop) => br ^ name ! prop }
}
This prints (for a passing Monoid[PositiveInt] instance):
[info] TestSpec
[info]
[info] PositiveInt should pass the Monoid laws
[info] + monoid.semigroup.associative
[info] + monoid.left identity
[info] + monoid.right identity
[info]
[info] Total for specification TestSpec
[info] Finished in 91 ms
[info] 3 examples, 300 expectations, 0 failure, 0 error
Related
I have a complex module written in Chisel. I'm using chiseltest to verify its operation. The test is failing. I want to be able to inspect the module's internal wire values to debug what is going wrong. Since the PeekPokeTester only allows me to inspect the value of the io signals, how can I inspect the internal wires?
Here is an example:
import chisel3._
class MyModule extends Module {
val io = IO(new Bundle {
val a = Input(Bool())
val b = Input(Bool())
val c = Input(Bool())
val d = Output(Bool())
})
val i = Wire(Bool())
i := io.a ^ io.b
io.d := i | io.c
}
import chisel3._
import chisel3.tester._
import org.scalatest.FreeSpec
class MyModuleTest extends FreeSpec with ChiselScalatestTester {
"MyModule should work properly" in {
test(new MyModule) { dut =>
dut.io.a.poke(true.B)
dut.io.b.poke(false.B)
dut.io.c.poke(false.B)
dut.i.expect(true.B) // This line throws a java.util.NoSuchElementException
// : key not found: Bool(Wire in MyModule)
}
}
}
How can I inspect the intermediate value "i"?
There's a few ways to do this.
1 ) Turn on VCD output by adding an annotation to your test, as in
import chiseltest.experimental.TestOptionBuilder._
import treadle._
...
test(new MyModule).withAnnotations(Seq(WriteVcdAnnotation)) { dut =>
The .vcd file will be placed in the relevant test_run_dir/ you can view it with GtkWave or similar
2 ) add printf statements to your module.
3 ) There is a simulation shell in the Treadle Repo that allows you to peek poke and step based on a firrtl file (the firrtl file should be in the same test_run_dir/ directory as above). There is A bit of documentation here
Good luck!
I am new Play/Scala and started porting a Spring Boot RestAPI to Play2 as a learning exercise.
In Java/SpringRest ,its simply a matter of annotating POJOs and the JSon library handle the serialize/deserialization automatically.
According to every Play2/Scala tutorial I read, I have to write a Writer/Reader for each model/case class as follows
implicit val writesItem = Writes[ClusterStatus] {
case ClusterStatus(gpuFreeMemory, gpuTotalMemory, labelsLoaded, status) =>
Json.obj("gpuFreeMemory" -> gpuFreeMemory,
"gpuTotalMemory" -> gpuTotalMemory,
"labelsLoaded" -> labelsLoaded,
"status" -> status)
}
//HTTP method
def status() = Action { request =>
val status: ClusterStatus = clusterService.status()
Ok(Json.toJson(status))
}
This means If have a large domain model/response model, I have to write a lot of Writers/Readers for serialize/deserialization?
Is there any simpler way to handle this?
You can give a try to "com.typesafe.play" %% "play-json" % "2.7.2". For using that you just need to do the below steps:
1) Add below dependencies(Use version according to your project):
"com.typesafe.play" %% "play-json" % "2.7.2",
"net.liftweb" % "lift-json_2.11" % "2.6.2"
2) Define formats:
implicit val formats = DefaultFormats
implicit val yourCaseClassFormat= Json.format[YourCaseClass]
This format defines both read and writes for your case class.
Update:
I want to check a JSON document on his structure. I created a JSR223 Assertion with language groovy. My code to check the JSON structure looks like this:
import groovy.json.*;
import org.apache.jmeter.samplers;
def response = prev.getResponseDataAsString();
log.info("Response" + response);
def json = new JsonSlurper().parseText(response);
//tests
def query = json.query;
assert query instanceof String;
def totalResults = json.totalResults;
assert query instanceof Integer;
def from = json.from;
assert from instanceof Integer;
def to = json.to;
assert to instanceof Integer;
assertionResult = new AssertionResult("Assertion failed! See log file.");
assertionResult.setError(true);
assertionResult.setFailureMessage(e.toString());
The validation in the JMeter logfile works great.
But in my View Result Tree, i got the following error message:
Assertion error: true
Assertion failure: false
Assertion failure message: javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script27.groovy: 2: unable to resolve class org.apache.jmeter.samplers
# line 2, column 1.
import org.apache.jmeter.samplers;
^
Script27.groovy: 21: unable to resolve class AssertionResult
# line 21, column 19.
assertionResult = new AssertionResult("Assertion failed! See log file.");
^
2 errors
I want to see if the test result is successful or not.
How to fix this issue?
Don't instantiate AssertionResult class, it is pre-defined
Don't use Groovy assert keyword, it won't fail the parent sampler as expected, refer below example simple code
if (1 != 2) {
AssertionResult.setFailure(true)
AssertionResult.setFailureMessage("1 is not equal to 2")
}
once you get it working like below:
you can start modifying your tests as required
See How to Use JMeter Assertions in Three Easy Steps guide to learn more about using assertions in JMeter tests.
Upgrading circe from 0.4.1 to 0.7.0 broke the following code:
import shapeless._
import syntax.singleton._
import io.circe.generic.auto._
.run[Record.`'transaction_id -> Int`.T](transport)
def run[A](transport: Json => Future[Json])(implicit decoder: Decoder[A], exec: ExecutionContext): Future[A]
With the following error:
could not find implicit value for parameter decoder: io.circe.Decoder[shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("transaction_id")],Int],shapeless.HNil]]
[error] .run[Record.`'transaction_id -> Int`.T](transport)
[error] ^
Am I missing some import here or are these encoders/decoders not available in circe anymore?
Instances for Shapeless's hlists, records, etc. were moved to a separate circe-shapes module in the circe 0.6.0 release. If you add this module to your build, the following should just work:
import io.circe.jawn.decode, io.circe.shapes._
import shapeless._, record.Record, syntax.singleton._
val doc = """{ "transaction_id": 1 }"""
val res = decode[Record.`'transaction_id -> Int`.T](doc)
The motivation for moving these instances was that the improved generic derivation introduced in 0.6 meant that they were no longer necessary, and keeping them out of implicit scope when they're not needed is both cleaner and potentially supports faster compile times. The new circe-shapes module also includes features that were not available in circe-generic, such as instances for coproducts.
I am rather new to CHISEL.
Is it possible for CHISEL testbench to receive an arg passed in during runtime?
For example, sbt run --backend c --compile --test --genHarness --dut1
--dut1 is meant to be received by the testbench as an arg. It will be used to determine which DUT to be instantiated.
Yes, I believe that would work.
sbt "project myproject" "run my_arg --backend c --targetDir my_target_dir"
You can catch that in your own main, strip out your arguments, and pass Chisel its arguments. Something sort of like this:
````
object top_main {
def main(args: Array[String]): Unit = {
val my_arg = args(0)
val chiselArgs = ArrayBufferString
chiselMain(chiselArgs.toArray, () => iforgettheexactsyntax(my_arg))
}
}
Check out (Chisel runtime error in test harness) for an example main that invokes Chisel.