Skip to content

Instantly share code, notes, and snippets.

@Michael-J-Ward
Created June 17, 2016 18:29
Show Gist options
  • Save Michael-J-Ward/fdc99996266c6e837bfc036e1d9879f7 to your computer and use it in GitHub Desktop.
Save Michael-J-Ward/fdc99996266c6e837bfc036e1d9879f7 to your computer and use it in GitHub Desktop.
test suite for week2 of Functional Programming in scala
package funsets
import org.scalatest.FunSuite
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
/**
* This class is a test suite for the methods in object FunSets. To run
* the test suite, you can either:
* - run the "test" command in the SBT console
* - right-click the file in eclipse and chose "Run As" - "JUnit Test"
*/
@RunWith(classOf[JUnitRunner])
class FunSetSuite extends FunSuite {
/**
* Link to the scaladoc - very clear and detailed tutorial of FunSuite
*
* http://doc.scalatest.org/1.9.1/index.html#org.scalatest.FunSuite
*
* Operators
* - test
* - ignore
* - pending
*/
/**
* Tests are written using the "test" operator and the "assert" method.
*/
// test("string take") {
// val message = "hello, world"
// assert(message.take(5) == "hello")
// }
/**
* For ScalaTest tests, there exists a special equality operator "===" that
* can be used inside "assert". If the assertion fails, the two values will
* be printed in the error message. Otherwise, when using "==", the test
* error message will only say "assertion failed", without showing the values.
*
* Try it out! Change the values so that the assertion fails, and look at the
* error message.
*/
import FunSets._
test("adding ints") {
assert(1 + 2 === 3)
}
test("contains is implemented") {
assert(contains(x => true, 100))
}
/**
* When writing tests, one would often like to re-use certain values for multiple
* tests. For instance, we would like to create an Int-set and have multiple test
* about it.
*
* Instead of copy-pasting the code for creating the set into every test, we can
* store it in the test class using a val:
*
* val s1 = singletonSet(1)
*
* However, what happens if the method "singletonSet" has a bug and crashes? Then
* the test methods are not even executed, because creating an instance of the
* test class fails!
*
* Therefore, we put the shared values into a separate trait (traits are like
* abstract classes), and create an instance inside each test method.
*
*/
trait TestSets {
val s1 = singletonSet(1)
val s2 = singletonSet(2)
val s3 = singletonSet(3)
val s4 = singletonSet(4)
val s13 = singletonSet(13)
val s169 = singletonSet(13*13)
val s400 = singletonSet(400)
val above5 = (x: Int) => x > 5
val below8 = (x: Int) => x < 8
val evens = (x: Int) => x%2 == 0
val odds = (x: Int) => x%2 == 1
val squared = (x: Int) => x*x
val cubed = (x: Int) => x*x*x
val negatives = (x: Int) => x < 0
val nonnegatives = (x: Int) => x > -1
}
/**
* This test is currently disabled (by using "ignore") because the method
* "singletonSet" is not yet implemented and the test would fail.
*
* Once you finish your implementation of "singletonSet", exchange the
* function "ignore" by "test".
*/
test("singletonSet(1) contains 1") {
/**
* We create a new instance of the "TestSets" trait, this gives us access
* to the values "s1" to "s3".
*/
new TestSets {
/**
* The string argument of "assert" is a message that is printed in case
* the test fails. This helps identifying which assertion failed.
*/
assert(contains(s1, 1), "Singleton")
}
}
test("union contains all elements of each set") {
new TestSets {
val s = union(s1, s2)
assert(contains(s, 1), "Union 1")
assert(contains(s, 2), "Union 2")
assert(!contains(s, 3), "Union 3")
}
}
test("finite intersection test") {
new TestSets {
val s = intersect(above5, below8)
assert(contains(s, 6), "6 is above5 and below8")
assert(!contains(s, 4), "4 is not above5")
assert(!contains(s, 9), "9 is not below8")
}
}
test("finite difference test") {
new TestSets {
val between0and8 = intersect(nonnegatives, below8)
val evensBelow8 = diff(between0and8,odds)
val oddsBelow8 = diff(between0and8, evens)
assert(contains(evensBelow8,4), "4 is even and below8")
assert(!contains(evensBelow8, 9), "10 is even but not below 8")
assert(contains(oddsBelow8, 3), "3 is odd and below8")
assert(!contains(oddsBelow8, 2), "2 is below 8 but not odd")
}
}
test("finite filter test") {
new TestSets {
val between0and8 = intersect(nonnegatives, below8)
val evensBelow8 = filter(between0and8, evens)
val oddsBelow8 = filter(between0and8, odds)
assert(contains(evensBelow8,4), "4 is even and below8")
assert(!contains(evensBelow8, 9), "10 is even but not below 8")
assert(contains(oddsBelow8, 3), "3 is odd and below8")
assert(!contains(oddsBelow8, 2), "2 is below 8 but not odd")
}
}
test("finite forall test") {
new TestSets {
val between0and8 = intersect(nonnegatives, below8)
val evensBelow8 = diff(between0and8,odds)
val oddsBelow8 = diff(between0and8, evens)
assert(forall(evensBelow8,evens), "only evens in [0,2,4,6,8]")
assert(forall(s2, evens), "2 is even")
assert(forall(oddsBelow8, odds), "[1,3,5,7] are odd")
assert(forall(intersect(s1,s3), odds), "1 and 3 are odd")
}
}
test("finite exists test") {
new TestSets {
val between0and8 = intersect(nonnegatives, below8)
val evensBelow8 = diff(between0and8,odds)
val oddsBelow8 = diff(between0and8, evens)
assert(exists(between0and8,evens), "an even exists between 0 and 8")
assert(exists(between0and8, odds), "an odd exists between 0 and 8")
assert(!exists(odds, evens), "no odds are even")
assert(!exists(negatives, nonnegatives), "no negatives are nonnegatives")
}
}
test("finite mapped test") {
new TestSets {
val between0and8 = intersect(nonnegatives, below8)
val evensBelow8 = diff(between0and8,odds)
val oddsBelow8 = diff(between0and8, evens)
val m1 = map(s13, squared)
val m2 = map(odds, cubed)
val m3 = map(negatives, squared)
val m4 = map(negatives, cubed)
assert(exists(m1,s169), "169 is in 13 squared")
assert(forall(m1, s169), "13 squared is only 169")
assert(forall(m2, odds), "all cubed odds are odd")
assert(forall(m3, nonnegatives), "all squares of negatives are nonnegatives")
assert(forall(m4, negatives), "all cubes of negatives are negatives")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment