Skip to content

Instantly share code, notes, and snippets.

View bvenners's full-sized avatar

Bill Venners bvenners

View GitHub Profile
// Proposed ehancement to ScalaTest to surface more info about compiler errors
// Existing syntax
// Assertions:
assertDoesNotCompile("val i: String = 1") // Expects either a type or parse error
assertTypeError("val i: String = 1") // Expects just a type error (not a parse error)
assertCompiles("val i: Int = 1") // Expects no error during compilation
// Matchers:
"val i: String = 1" shouldNot compile // Expects either a type or parse error
"val i: String = 1" shouldNot typeCheck // Expects either a type error
:paste
type ErrorMessage = String
trait LeftBiased
trait RightBiased
sealed abstract class Or[+G, +B] extends LeftBiased {
def map[H](f: G => H): H Or B
@bvenners
bvenners / ScalaTestAssertions.scala
Created February 2, 2016 03:37
ScalaTest Assertions and Diagrammed Assertions
scala> import org.scalatest.Assertions._
import org.scalatest.Assertions._
scala> val x = 1
x: Int = 1
scala> assert(List(1, 2, 3).contains(x) && x > 1)
org.scalatest.exceptions.TestFailedException: List(1, 2, 3) contained 1, but 1 was not greater than 1
at org.scalatest.Assertions$class.newAssertionFailedException(Assertions.scala:541)
at org.scalatest.Assertions$.newAssertionFailedException(Assertions.scala:1414)
// Here's a typeclass trait for types that can be sliced
trait Slicing[T] {
def slice(o: T, from: Int, until: Int): T
}
// The companion object provides impicits for String and Vector
object Slicing {
implicit val slicingNatureOfString: Slicing[String] =
new Slicing[String] {
@bvenners
bvenners / gist:aa9a78afb91e25795d01
Last active August 29, 2015 14:12
An example of matcher composition in ScalaTest
//
// TLDR: In ScalaTest, matcher composition is simply function composition.
//
//
// The beOdd matcher in the documentation for org.scalatest.matchers.Matcher is simple, but it will
// concatenate strings that are not needed. If you want to avoid that as a (premature) performance
// optimization, you can write it like this:
//
scala> val beOdd =
@bvenners
bvenners / gist:844e9a83687d0cd3c80f
Last active August 29, 2015 14:08
Currently brewing in Scalactic master: bounded AnyVal types, including Pos (a positive Int)
scala> import org.scalactic.numbers._
import numbers._
// Pos is a type that ensures its "contained" value is a positive Int. I put "contained"
// in scare quotes because Pos is an AnyVal, so it should only box when an Int would box.
// You can create them directly with positive integer literals, like this:
scala> Pos(3)
res0: org.scalactic.numbers.Pos = Pos(3)
// If you pass an Int variable, or a non-positive Int literal, to this factory method, it
@bvenners
bvenners / gist:b129cccf6d6486316030
Created November 5, 2014 08:12
Example showing Scalactic's Validation used to accumulate errors with the "when" combinator
scala> import org.scalactic._
import org.scalactic._
// A Validation is either a Pass or a Fail. A Validation is like an
// Option with the reverse attitude: Pass is like None, it contains no
// value and just means the value being validated is OK as is. Fail is
// like Some, it holds an error value describing the validation failure.
scala> def isPositive(i: Int): Validation[ErrorMessage] =
| if (i > 0) Pass else Fail(s"$i was not positive")
isPositive: (i: Int)org.scalactic.Validation[org.scalactic.ErrorMessage]
@bvenners
bvenners / gist:6e2d9451760b7062fbbc
Created October 23, 2014 20:11
Shorthand form with existential type
// Can also do this:
scala> def addBippy(set: EquaSets[String]#EquaSet): set.path.EquaSet = {
| set.copyInto(set.path) union set.path.EquaSet("bippy")
| }
addBippy: (set: org.scalactic.EquaSets[String]#EquaSet)set.path.EquaSet
scala> val lowered = SortedEquaSets[String](StringNormalizations.lowerCased.toOrderingEquality)
lowered: org.scalactic.SortedEquaSets[String] = org.scalactic.SortedEquaSets@26273e89
@bvenners
bvenners / gist:8eec1cd4eb632de61e4a
Last active August 29, 2015 14:08
Using EquaSets in methods, take 2
// This is from github ScalaTest master, not in any release:
// Here's a method that takes a general one. This method asks the passed EquaSet
// for its enclosing EquaSets, and stores it in variable path. It then "copies"
// the passed EquaSet into the new path, after which it can union with a newly
// created EquaSet at the same path and return it.
scala> def addBippy(set: EquaSets[String]#EquaSet): EquaSets[String]#EquaSet = {
| val path = set.enclosingEquaSets
| val relocated = set.copyInto(path)
| relocated union path.EquaSet("bippy")
@bvenners
bvenners / gist:c5efdfe168305e26f208
Created October 22, 2014 19:51
Using EquaSets passed to methods
//
// This gist shows how the compiler will deal with EquaSets as method parameters.
// In short, the compiler will let you do anything that is known to be OK. In
// particular, it won't let you union, intersect, or diff two EquaSets unless
// the full path dependent type is known and matches.
//
scala> import org.scalactic._
scala> val trimmed = EquaSets[String](StringNormalizations.trimmed.toHashingEquality)
trimmed: org.scalactic.EquaSets[String] = org.scalactic.EquaSets@2c011b16