|
Scala example source code file (MapTest.scala)
The MapTest.scala Scala example source code
package scalaz
import org.scalacheck.Prop.forAll
import scala.util.Random
object MapTest extends SpecLite {
import org.scalacheck.Arbitrary
import scalaz.scalacheck.ScalazProperties._
import scalaz.scalacheck.ScalazArbitrary._
import std.anyVal._
import std.list._
import std.string._
import std.option._
import std.tuple._
import syntax.std.option._
import ==>>._
def structurallySound[A: Order: Show, B: Equal: Show](m: A ==>> B) = {
isSortedByKey(m)
isBalanced(m)
}
private def isSortedByKey[A: Order: Show, B: Equal: Show](m: A ==>> B) = {
val al = m.toAscList
al must_===(al.sortBy(_._1)(Order[A].toScalaOrdering))
}
private def isBalanced[A, B](m: A ==>> B) = {
def isWeightsValid(l: A ==>> B, r: A ==>> B): Boolean = {
val sizeL = if (l.size == 0) 1 else l.size
val sizeR = if (r.size == 0) 1 else r.size
(sizeL <= sizeR * delta) && (sizeR <= sizeL * delta)
}
def go(mab: A ==>> B): Boolean =
mab match {
case Tip() =>
true
case Bin(_, _, l, r) =>
if (isWeightsValid(l, r)) go(l) && go(r)
else false
}
go(m) must_=== true
}
"findLeft/findRight" in {
val a = ==>>.fromFoldable((1 to 5).map(n => n -> n).toList)
Foldable[Int ==>> ?].findLeft(a)(_ % 2 == 0) must_=== Some(2)
Foldable[Int ==>> ?].findRight(a)(_ % 2 == 0) must_=== Some(4)
}
"findLeft" ! forAll{ (a: Int ==>> Int) =>
val f = (_: Int) % 3 == 0
Foldable[Int ==>> ?].findLeft(a)(f) must_=== Foldable[List].findLeft(a.values)(f)
}
"findRight" ! forAll{ (a: Int ==>> Int) =>
val f = (_: Int) % 3 == 0
Foldable[Int ==>> ?].findRight(a)(f) must_=== Foldable[List].findRight(a.values)(f)
}
"index" ! forAll { (a: Int ==>> Int, i: Byte) =>
val F = Foldable[Int ==>> ?]
F.index(a, i) must_=== a.toList.lift(i).map(_._2)
F.index(a, -1) must_=== None
F.index(a, 0) must_=== a.findMin.map(_._2)
F.index(a, a.size - 1) must_=== a.findMax.map(_._2)
F.index(a, a.size) must_=== None
}
"equals/hashCode" ! forAll { a: Int ==>> Int =>
val b = ==>>.fromList(Random.shuffle(a.toList))
a must_== b
a.## must_=== b.##
}
"minViewWithKey" ! forAll { a: Int ==>> Int =>
a.minViewWithKey match {
case None =>
a.size must_=== 0
case Some(b) =>
structurallySound(b._2)
a.findMin must_=== Some(b._1)
(b._2.size + 1) must_=== a.size
(b._2 + b._1) must_=== a
}
}
"maxViewWithKey" ! forAll { a: Int ==>> Int =>
a.maxViewWithKey match {
case None =>
a.size must_=== 0
case Some(b) =>
structurallySound(b._2)
a.findMax must_=== Some(b._1)
(b._2.size + 1) must_=== a.size
(b._2 + b._1) must_=== a
}
}
"findMin" ! forAll { a: Int ==>> Int =>
a.findMin must_=== {
if(a.isEmpty) None
else Some(a.toList.minBy(_._1))
}
}
"findMax" ! forAll { a: Int ==>> Int =>
a.findMax must_=== {
if(a.isEmpty) None
else Some(a.toList.maxBy(_._1))
}
}
"deleteMin" ! forAll { a: Int ==>> Int =>
val b = a.deleteMin
structurallySound(b)
if(a.isEmpty){
b.isEmpty must_=== true
}else{
(b.size + 1) must_=== a.size
b must_=== a.delete(a.findMin.get._1)
}
}
"deleteMax" ! forAll { a: Int ==>> Int =>
val b = a.deleteMax
structurallySound(b)
if(a.isEmpty){
b.isEmpty must_=== true
}else{
(b.size + 1) must_=== a.size
b must_=== a.delete(a.findMax.get._1)
}
}
"deleteAt" ! forAll { (a: Int ==>> Int, i: Byte) =>
if(a.size != 0){
val n = i.toInt.abs % a.size
val b = a.deleteAt(n)
structurallySound(b)
(a.size - 1) must_=== b.size
b.member(a.keys(n)) must_=== false
(b + a.elemAt(n).get) must_=== a
}
}
"==>> fromList" ! {
fromList(List.empty[(Int, String)]) must_===(empty[Int, String])
fromList(List(5 -> "a", 3 -> "b")) must_===(fromList(List(3 -> "b", 5 -> "a")))
fromList(List(5 ->"a", 3 -> "b", 5 -> "c")) must_===(fromList(List(5 -> "c", 3 -> "b")))
fromList(List(5 -> "c", 3 -> "b", 5 -> "a")) must_===(fromList(List(5 -> "a", 3 -> "b")))
}
"Testing empty map" should {
"be 0 for an empty map" in {
empty.size must_== 0
}
"be 1 for a singleton map" in {
singleton(1, 'a').size must_== 1
}
"be 3 for the list [(1,'a'), (2,'c'), (3,'b')])" in {
fromList(List((1,'a'), (2,'c'), (3,'b'))).size must_== 3
}
}
"Membership in map" should {
"be true if element contained" in {
fromList(List((5, 'a'), (3, 'b'))).member(5) must_== true
}
"be false if not contained" in {
fromList(List((5, 'a'), (3, 'b'))).member(1) must_== false
}
}
"Non-membership" should {
"be false for contained member" in {
fromList(List((5, 'a'), (3, 'b'))).notMember(5) must_== false
}
"be true for non-contained member" in {
fromList(List((5, 'a'), (3, 'b'))).notMember(1) must_== true
}
}
"elemAt" should {
val d = fromList(List(5 -> "a", 3 -> "b"))
"find successful result" in {
d.elemAt(0) must_== (3, "b").some
d.elemAt(1) must_== (5, "a").some
}
"not find a match" in {
d.elemAt(2) must_== None
}
"elemAt" ! forAll { (a: Byte ==>> Int, b: Byte) =>
a.elemAt(b) must_=== a.toList.lift(b)
}
}
"==>> conversions" should {
"toAscList" in {
import std.tuple._
implicit val listTupleShow = Show[List[(Int, String)]]
fromList(List(5 -> "a", 3 -> "b")).toAscList must_===(fromList(List(3 -> "b", 5 -> "a")).toAscList)
fromList(List(5 -> "a", 7 -> "c", 3 -> "b")) must_===(fromList(List(3 -> "b", 5 -> "a", 7 -> "c")))
}
}
"==>> lookups" should {
val d = fromList(List(5 -> "a", 3 -> "b"))
"value lookup" in {
fromList(List(("John","Sales"), ("Bob","IT"))).lookup("John") must_===(Some("Sales"))
fromList(List(("John","Sales"), ("Bob","IT"))).lookup("Sarah") must_===(None)
}
"index lookup" in {
d.lookupIndex(2).isDefined must_== false
d.lookupIndex(3).get must_== 0
d.lookupIndex(5).get must_== 1
d.lookupIndex(6).isDefined must_== false
}
"value lookupLT" in {
fromList(List((3,"a"), (5,"b"))).lookupLT(3) must_=== None
fromList(List((3,"a"), (5,"b"))).lookupLT(4) must_=== Some((3, "a"))
}
"value lookupGT" in {
fromList(List((3,"a"), (5,"b"))).lookupGT(5) must_=== None
fromList(List((3,"a"), (5,"b"))).lookupGT(3) must_=== Some((5, "b"))
}
"value lookupLE" in {
fromList(List((3,"a"), (5,"b"))).lookupLE(2) must_=== None
fromList(List((3,"a"), (5,"b"))).lookupLE(3) must_=== Some((3, "a"))
fromList(List((3,"a"), (5,"b"))).lookupLE(4) must_=== Some((3, "a"))
}
"value lookupGE" in {
fromList(List((3,"a"), (5,"b"))).lookupGE(6) must_=== None
fromList(List((3,"a"), (5,"b"))).lookupGE(5) must_=== Some((5, "b"))
fromList(List((3,"a"), (5,"b"))).lookupGE(4) must_=== Some((5, "b"))
}
"lookup" ! forAll { (a: Byte ==>> Int, n: Byte) =>
a.lookup(n) must_=== a.toList.find(_._1 == n).map(_._2)
}
"lookupAssoc" ! forAll { (a: Byte ==>> Int, n: Byte) =>
a.lookupAssoc(n) must_=== a.lookup(n).map(n -> _)
}
"lookupIndex" ! forAll { (a: Byte ==>> Int, n: Byte) =>
val x = a.keys.indexOf(n)
a.lookupIndex(n) must_=== (if(x < 0) None else Some(x))
a.lookupIndex(n).foreach{ b =>
a.elemAt(b).map(_._1) must_=== Some(n)
}
}
"lookupLT" ! forAll { (a: Int ==>> Int) =>
if (a.size == 0) {
val r = Random.nextInt()
a.lookupLT(r) must_=== None
}
else {
(0 until a.keys.size).foreach { i =>
val (k, v) = a.elemAt(i).get
a.lookupLT(k) must_=== a.elemAt(i-1)
if (k != Int.MaxValue) {
a.lookupLT(k+1) must_=== Some((k, v))
}
}
}
}
"lookupGT" ! forAll { (a: Int ==>> Int) =>
if (a.size == 0) {
val r = Random.nextInt()
a.lookupGT(r) must_=== None
}
else {
(0 until a.keys.size).foreach { i =>
val (k, v) = a.elemAt(i).get
a.lookupGT(k) must_=== a.elemAt(i+1)
if (k != Int.MinValue) {
a.lookupGT(k-1) must_=== Some((k, v))
}
}
}
}
"lookupLE" ! forAll { (a: Int ==>> Int) =>
if (a.size == 0) {
val r = Random.nextInt()
a.lookupLE(r) must_=== None
}
else {
(0 until a.keys.size).foreach { i =>
val (k, v) = a.elemAt(i).get
a.lookupLE(k) must_=== Some((k, v))
if (k != Int.MinValue) {
a.lookupLE(k-1) must_=== a.elemAt(i-1)
}
}
}
}
"lookupGE" ! forAll { (a: Int ==>> Int) =>
if (a.size == 0) {
val r = Random.nextInt()
a.lookupGE(r) must_=== None
}
else {
(0 until a.keys.size).foreach { i =>
val (k, v) = a.elemAt(i).get
a.lookupGE(k) must_=== Some((k, v))
if (k != Int.MaxValue) {
a.lookupGE(k+1) must_=== a.elemAt(i+1)
}
}
}
}
}
"split" should {
"splitRoot" ! forAll { a: Int ==>> Int =>
a match {
case Tip() =>
a.splitRoot must_=== List.empty[Int ==>> Int]
case Bin(k, x, l, r) =>
val List(l2, kv, r2) = a.splitRoot
structurallySound(l2)
structurallySound(r2)
l2 must_=== l
r2 must_=== r
kv must_=== singleton(k, x)
l2.union(r2).union(kv) must_=== a
}
}
}
"updateAt" should {
"succeed" in {
// TODO: This is a problem as the function 'updateAt' is not total - any thoughts?
//-- > updateAt (\ _ _ -> Just "x") 0 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
//-- > updateAt (\ _ _ -> Just "x") 1 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
//-- > updateAt (\ _ _ -> Just "x") 2 (fromList [(5,"a"), (3,"b")]) Error: index out of range
//-- > updateAt (\ _ _ -> Just "x") (-1) (fromList [(5,"a"), (3,"b")]) Error: index out of range
//-- > updateAt (\_ _ -> Nothing) 0 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
//-- > updateAt (\_ _ -> Nothing) 1 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
//-- > updateAt (\_ _ -> Nothing) 2 (fromList [(5,"a"), (3,"b")]) Error: index out of range
//-- > updateAt (\_ _ -> Nothing) (-1) (fromList [(5,"a"), (3,"b")]) Error: index out of range
val d = fromList(List(5 -> "a", 3 -> "b"))
d.updateAt(0, (_, _) => "x".some) must_===(fromList(List(3 -> "x", 5 -> "a")))
d.updateAt(1, (_, _) => "x".some) must_===(fromList(List(3 -> "b", 5 -> "x")))
//d.updateAt(2, (_, _) => "x".some) must_===(empty[Int, String])
d.updateAt(0, (_, _) => None) must_===(singleton(5, "a"))
d.updateAt(1, (_, _) => None) must_===(singleton(3, "b"))
}
}
"delete" should {
"remove an element" in {
fromList(List((5,"a"), (3,"b"))).delete(5) must_===(singleton(3, "b"))
}
"not remove an element" in {
fromList(List((5,"a"), (3,"b"))).delete(7) must_===(fromList(List((5,"a"), (3,"b"))))
}
"not remove from an empty map" in {
empty.delete(5) must_===(empty[Int, Int])
}
"be sound" ! forAll {(m: Int ==>> Int, i: Int) =>
val a = m delete i
structurallySound(a)
(a member i) must_=== false
if(m member i)
(m.size - 1) must_=== a.size
else
m must_=== a
}
}
"==>> insertion" should {
"insert" in {
fromList(List(5 -> "a", 3 -> "b")).insert(5, "x") must_===(fromList(List(3 -> "b", 5 -> "x"))) // Replacement
fromList(List((5,"a"), (3,"b"))).insert(7,"x") must_===(fromList(List((3,"b"), (5,"a"), (7,"x")))) // Addition of new key
empty.insert(5, "x") must_===(singleton(5, "x"))
}
"insert sound" ! forAll {(m: Int ==>> Int, a: Int, b: Int) =>
val c = m insert (a, b)
structurallySound(c)
if(m member a)
m.size must_=== c.size
else
(m.size + 1) must_=== c.size
c.lookup(a) must_=== Some(b)
}
"insertWith" in {
val r = fromList(List(5 -> "a", 3 -> "b")).insertWith(_ + _, 5, "xxx")
r must_===(fromList(List(3 -> "b", 5 -> "xxxa")))
fromList(List(5 -> "a", 3 -> "b")).insertWith(_ + _, 7, "xxx") must_===(fromList(List(3 -> "b", 5 -> "a", 7 -> "xxx")))
empty[Int, String].insertWith(_ + _, 5, "xxx") must_===(singleton(5, "xxx"))
}
"insertWithKey" in {
val f = (k: Int, a: String, b: String) => k.toString + ":" + a + "|" + b
fromList(List(5 -> "a", 3 -> "b")).insertWithKey(f, 5, "xxx") must_===(fromList(List(3 -> "b", 5 -> "5:xxx|a")))
fromList(List(5 -> "a", 3 -> "b")).insertWithKey(f, 7, "xxx") must_===(fromList(List(3 -> "b", 5 -> "a", 7 -> "xxx")))
empty.insertWithKey(f, 5, "xxx") must_===(singleton(5, "xxx"))
}
"insertWithKey sound" ! forAll {(m: Int ==>> Int, a: Int, b: Int) =>
structurallySound(m insertWithKey ((_, _, b) => b, a, b))
}
}
"==>> from a list" should {
"equivalence to insert on empty ==>>" in {
empty.insert(2,3).insert(3,4) must_===(fromList(List(2 -> 3, 3 -> 4)))
}
"be order-insensitive" ! forAll {(am: Map[Int, Int]) =>
val al = am.toList
fromList(al.reverse) must_===(fromList(al))
}
"create a valid map from empty list" in {
fromList(List.empty[(Int, Int)]) must_===(empty[Int, Int])
}
}
"==>> union operations" should {
"be sound" ! forAll {(a: Int ==>> Int, b: Int ==>> Int) =>
val c = a union b
structurallySound(c)
(a.keySet union b.keySet) must_=== c.keySet
}
"union" in {
fromList(List((5, "a"), (3, "b"))) union fromList(List((5, "A"), (7, "C"))) must_== fromList(List((3, "b"), (5, "a"), (7, "C")))
}
"commute" ! forAll {(a: Int ==>> Int, b: Int ==>> Int) =>
(a unionWith b)(_ + _) must_===((b unionWith a)(_ + _))
}
"be idempotent" ! forAll {(a: Int ==>> Int, b: Int ==>> Int) =>
val ab = a union b
ab union a must_===(ab)
ab union b must_===(ab)
}
"unions" in {
unions(List(
fromList(List((5, "a"), (3, "b"))),
fromList(List((5, "A"), (7, "C"))),
fromList(List((5, "A3"), (3, "B3")))
)) must_== fromList(List((3, "b"), (5, "a"), (7, "C")))
unions(List(fromList(List(5 -> "A3", 3 -> "B3")), fromList(List(5 -> "A", 7 -> "C")), fromList(List(5 -> "a", 3 -> "b")))) must_== fromList(List(3 -> "B3", 5 -> "A3", 7 -> "C"))
}
"unionWith" in {
val adder = (a: String, b: String) => Semigroup[String].append(a, b)
val r = fromList(List(5 -> "a", 3 -> "b")).unionWith(fromList(List(5 -> "A", 7 -> "C")))(adder)
r must_== fromList(List(3 -> "b", 5 -> "aA", 7 -> "C"))
}
"unionWithKey" in {
val f = (key: Int, left: String, right: String) => key.toString + ":" + left + "|" + right
val r = fromList(List(5 -> "a", 3 -> "b")).unionWithKey(fromList(List(5 -> "A", 7 -> "C")))(f)
r must_== fromList(List(3 -> "b", 5 -> "5:a|A", 7 -> "C"))
}
}
"==>> difference operations" should {
"difference" in {
val r = fromList(List(5 -> "a", 3 -> "b")).difference(fromList(List(5 -> "A", 7 -> "C")))
r must_== singleton[Int, String](3, "b")
}
"be idempotent" ! forAll {(a: Int ==>> Int, b: Int ==>> Int) =>
val ab = a \\ b
(ab \\ b) must_===(ab)
}
"be idempotent (in one case)" in {
val a = Bin(-1768028150,1831400640,Bin(-2147483648,2147483647,Tip(),Tip()),
Bin(-541865171,1,Tip(),Bin(1085869916,1066820187,Tip(),Tip())))
val b = Bin(0,1979991171,Tip(),Tip())
val ab = a \\ b
(ab \\ b) must_===(ab)
}
"produce right keyset" ! forAll {(a: Int ==>> Int, b: Int ==>> Int) =>
(a \\ b).keySet must_== (a.keySet \\ b.keySet)
}
"be an inverse" ! forAll {(a: Int ==>> Int) =>
(a \\ a) must_===(==>>.empty[Int, Int])
}
"syntax" in {
val r = fromList(List(5 -> "a", 3 -> "b")) \\ fromList(List(5 -> "A", 7 -> "C"))
r must_== singleton[Int, String](3, "b")
}
"differenceWith" in {
val f = (al: String, ar: String) => if (al == "b") Some(al + ":" + ar) else None
fromList(List(5 -> "a", 3 -> "b")).differenceWith(fromList(List(5 -> "A", 3 -> "B", 7 -> "C")))(f) must_===(singleton(3, "b:B"))
}
"differenceWithKey" in {
val f = (k: Int, al: String, ar: String) => if (al == "b") Some(k.toString + ":" + al + "|" + ar) else None
fromList(List(5 -> "a", 3 -> "b")).differenceWithKey(fromList(List(5 -> "A", 3 -> "B", 10 -> "C")))(f) must_===(singleton(3, "3:b|B"))
}
}
"==>> intersection operations" should {
"intersection" in {
val r = fromList(List(5 -> "a", 3 -> "b")) intersection fromList(List(5 -> "A", 7 -> "C"))
r must_== singleton(5, "a")
}
"intersect soundly" ! forAll {(a: Int ==>> Int, b: Int ==>> Int) =>
structurallySound(a intersection b)
}
"form an identity" ! forAll {(a: Int ==>> Int) =>
a intersection a must_===(a)
}
"commute" ! forAll {(a: Int ==>> Int, b: Int ==>> Int) =>
(a intersectionWith b)(_ + _) must_===((b intersectionWith a)(_ + _))
}
"commute (in one case)" in {
val a = Bin(1951314151,1,Bin(-1,1271148582,Tip(),Tip()),
Bin(2147483647,-1423766788,Tip(),Tip()))
val b = Bin(-12693552,-2147483648,
Bin(-1587083834,-729342404,Tip(),Tip()),
Bin(-1,0,Tip(),Tip()))
(a intersectionWith b)(_ + _) must_===((b intersectionWith a)(_ + _))
}
"intersectionWith" in {
val f = (a: String, b: String) => a + b
val r = fromList(List(5 -> "a", 3 -> "b")).intersectionWith(fromList(List(5 -> "A", 7 -> "C")))(f)
r must_== singleton(5, "aA")
}
"intersectionWithKey" in {
val f = (k: Int, al: String, ar: String) => k.toString + ":" + al + "|" + ar
val r = fromList(List(5 -> "a", 3 -> "b")).intersectionWithKey(fromList(List(5 -> "A", 7 -> "C")))(f)
r must_== singleton(5, "5:a|A")
}
}
"==>> update" should {
"adjust" in {
val f = "new " + (_: String)
fromList(List(5 -> "a", 3 -> "b")).adjust(5, f) must_===(fromList(List(3 -> "b", 5 -> "new a")))
fromList(List(5 -> "a", 3 -> "b")).adjust(7, f) must_===(fromList(List(3 -> "b", 5 -> "a")))
empty[Int, String].adjust(7, f) must_===(empty[Int, String])
}
"adjustWithKey" in {
val f = (k: Int, x: String) => k.toString + ":new " + x
fromList(List(5 -> "a", 3 -> "b")).adjustWithKey(5, f) must_===(fromList(List(3 -> "b", 5 -> "5:new a")))
fromList(List(5 -> "a", 3 -> "b")).adjustWithKey(7, f) must_===(fromList(List(3 -> "b", 5 -> "a")))
empty[Int, String].adjustWithKey(7, f) must_===(empty[Int, String])
}
"update" in {
val f = (x: String) => if (x == "a") Some("new a") else None
fromList(List(5 -> "a", 3 -> "b")).update(5, f) must_===(fromList(List(3 -> "b", 5 -> "new a")))
fromList(List(5 -> "a", 3 -> "b")).update(7, f) must_===(fromList(List(3 -> "b", 5 -> "a")))
fromList(List(5 -> "a", 3 -> "b")).update(3, f) must_===(singleton(5, "a"))
}
"updateWithKey" in {
val f = (k: Int, x: String) => if (x == "a") Some(k.toString + ":new a") else None
fromList(List(5 -> "a", 3 -> "b")).updateWithKey(5, f) must_===(fromList(List(3 -> "b", 5 -> "5:new a")))
fromList(List(5 -> "a", 3 -> "b")).updateWithKey(7, f) must_===(fromList(List(3 -> "b", 5 -> "a")))
fromList(List(5 -> "a", 3 -> "b")).updateWithKey(3, f) must_===(singleton(5, "a"))
}
"updateLookupWithKey" in {
import std.tuple._
val f = (k: Int, x: String) => if (x == "a") Some(k.toString + ":new a") else None
fromList(List(5 -> "a", 3 -> "b")).updateLookupWithKey(5, f) must_===((Some("5:new a"), fromList(List(3 -> "b", 5 -> "5:new a"))))
fromList(List(5 -> "a", 3 -> "b")).updateLookupWithKey(7, f) must_===((None, fromList(List(3 -> "b", 5 -> "a"))))
fromList(List(5 -> "a", 3 -> "b")).updateLookupWithKey(3, f) must_===((Some("b"), singleton(5, "a")))
}
"alter" in {
val f1 = (_: Option[String]) => none[String]
fromList(List(5 -> "a", 3 -> "b")).alter(7, f1) must_===(fromList(List(3 -> "b", 5 -> "a")))
fromList(List(5 -> "a", 3 -> "b")).alter(5, f1) must_===(singleton(3, "b"))
val f2 = (_: Option[String]) => "c".some
fromList(List(5 -> "a", 3 -> "b")).alter(7, f2) must_===(fromList(List(3 -> "b", 5 -> "a", 7 -> "c")))
fromList(List(5 -> "a", 3 -> "b")).alter(5, f2) must_===(fromList(List(3 -> "b", 5 -> "c")))
}
}
"==>> submap" should {
"isSubmapOfBy -> true" in {
val o = implicitly[Order[Int]]
fromList(List('a' -> 1)).isSubmapOfBy(fromList(List('a' -> 1, 'b' -> 2)), o.equal) must_== true
fromList(List('a' -> 1)).isSubmapOfBy(fromList(List('a' -> 1, 'b' -> 2)), o.lessThanOrEqual) must_== true
fromList(List('a' -> 1, 'b' -> 2)).isSubmapOfBy(fromList(List('a' -> 1, 'b' -> 2)), o.equal) must_== true
}
"isSubmapOfBy -> false" in {
val o = implicitly[Order[Int]]
fromList(List('a' -> 2)).isSubmapOfBy(fromList(List('a' -> 1, 'b' -> 2)), o.equal) must_== false
fromList(List('a' -> 1)).isSubmapOfBy(fromList(List('a' -> 1, 'b' -> 2)), o.lessThan) must_== false
fromList(List('a' -> 1, 'b' -> 2)).isSubmapOfBy(fromList(List('a' -> 1)), o.equal) must_== false
}
"isSubmapOf" ! forAll { (a: Byte ==>> Byte, b: Byte ==>> Byte) =>
if(a isSubmapOf b){
(a.keySet isSubsetOf b.keySet) must_=== true
a.difference(b) must_=== ==>>.empty
a.toList.foreach{case (k, v) => b.lookup(k) must_=== Some(v)}
}
}
}
"==>> filter" should {
val m = fromList(List(5 -> "a", 3 -> "b"))
"filter" in {
m.filter(_ > "a") must_===(singleton(3, "b"))
m.filter(_ > "x") must_===(empty[Int, String])
m.filter(_ < "a") must_===(empty[Int, String])
}
"be sound" ! forAll { (a: Byte ==>> Byte, n: Byte) =>
val b = a.filter(_ > n)
structurallySound(b)
fromList(a.toList.filter(_._2 > n)) must_=== b
}
}
"==>> partition" should {
val m = fromList(List(5 -> "a", 3 -> "b"))
"partition" in {
m.partition(_ > "a") must_===((singleton(3, "b"), singleton(5, "a")))
m.partition(_ < "x") must_===((fromList(List(3 -> "b", 5 -> "a")), empty[Int, String]))
m.partition(_ > "x") must_===((empty[Int, String], fromList(List(3 -> "b", 5 -> "a"))))
}
"be sound" ! forAll { (m: Int ==>> Int, n: Int) =>
val (ma, mb) = m.partition(n > _)
structurallySound(ma)
structurallySound(mb)
(ma union mb) must_=== m
}
"partitionWithKey" in {
m.partitionWithKey((k, _) => k > 3) must_===((singleton(5, "a"), singleton(3, "b")))
m.partitionWithKey((k, _) => k < 7) must_===((fromList(List(3 -> "b", 5 -> "a")), empty[Int, String]))
m.partitionWithKey((k, _) => k > 7) must_===((empty[Int, String], fromList(List(3 -> "b", 5 -> "a"))))
}
}
"==>> map" should {
import std.tuple._
"map" in {
fromList(List(5 -> "a", 3 -> "b")).map(_ + "x") must_===(fromList(List(3 -> "bx", 5 -> "ax")))
}
"mapWithKey" in {
val f = (k: Int, x: String) => k.toString + ":" + x
fromList(List(5 -> "a", 3 -> "b")).mapWithKey(f) must_===(fromList(List(3 -> "3:b", 5 -> "5:a")))
}
"mapAccum" in {
val f = (a: String, b: String) => (a + b, b + "X")
fromList(List(5 -> "a", 3 -> "b")).mapAccum("Everything: ")(f) must_===("Everything: ba", fromList(List(3 -> "bX", 5 -> "aX")))
}
"mapAccumWithKey" in {
val f = (a: String, k: Int, b: String) => (a + " " + k.toString + "-" + b, b + "X")
fromList(List(5 -> "a", 3 -> "b")).mapAccumWithKey("Everything:")(f) must_===("Everything: 3-b 5-a", fromList(List(3 -> "bX", 5 -> "aX")))
}
"mapKeys" in {
fromList(List(5 -> "a", 3 -> "b")).mapKeys(_ + 1) must_===(fromList(List(4 -> "b", 6 -> "a")))
fromList(List(1 -> "b", 2 -> "a", 3 -> "d", 4 -> "c")).mapKeys(_ => 1) must_===(singleton(1, "c"))
fromList(List(1 -> "b", 2 -> "a", 3 -> "d", 4 -> "c")).mapKeys(_ => 3) must_===(singleton(3, "c"))
}
"mapKeys sound" ! forAll { a: Int ==>> Int =>
val b = a.mapKeys(identity)
b must_=== a
structurallySound(b)
val f = (_: Int) % 10
val c = a.mapKeys(f)
c must_=== fromList(a.toList.map(x => (f(x._1), x._2)))
structurallySound(c)
}
"mapWithKeys" in {
fromList(List(1 -> "b", 2 -> "a", 3 -> "d", 4 -> "c")).mapKeysWith(_ => 1, _ + _) must_===(singleton(1, "cdab"))
fromList(List(1 -> "b", 2 -> "a", 3 -> "d", 4 -> "c")).mapKeysWith(_ => 3, _ + _) must_===(singleton(3, "cdab"))
}
"mapOption" in {
val f = (x: String) => if (x == "a") Some("new a") else None
fromList(List(5 -> "a", 3 -> "b")).mapOption(f) must_===(singleton(5, "new a"))
}
"mapOptionWithKey" in {
val f = (k: Int, _: String) => if (k < 5) Some("key : " + k.toString) else None
fromList(List(5 -> "a", 3 -> "b")).mapOptionWithKey(f) must_===(singleton(3, "key : 3"))
}
"mapEither" in {
val f = (a: String) => if (a < "c") \/.left(a) else \/.right(a)
val lst = fromList(List(5 -> "a", 3 -> "b", 1 -> "x", 7 -> "z"))
lst.mapEither(f) must_===((fromList(List(3 -> "b", 5 -> "a")), fromList(List(1 -> "x", 7 -> "z"))))
lst.mapEither((a: String) => \/.right(a)) must_===((empty[Int, String], lst))
}
"mapEitherWithKey" in {
val f = (k: Int, a: String) => if (k < 5) \/.left(k * 2) else \/.right(a + a)
val lst = fromList(List(5 -> "a", 3 -> "b", 1 -> "x", 7 -> "z"))
lst.mapEitherWithKey(f) must_===(fromList(List(1 -> 2, 3 -> 6)), fromList(List(5 -> "aa", 7 -> "zz")))
lst.mapEitherWithKey((_: Int, a: String) => \/.right(a)) must_===(empty[Int, String], lst)
}
}
"==>> traverse" should {
"traverseWithKey" in {
val f = (k: Int, v: Char) => if (k%2 == 1) Some((v + 1).toChar) else None
empty.traverseWithKey(f) must_=== Some(empty)
fromList(List(1 -> 'a', 5 -> 'e')).traverseWithKey(f) must_=== Some(fromList(List(1 -> 'b', 5 -> 'f')))
fromList(List(2 -> 'a')).traverseWithKey(f) must_=== None
}
"traverseWithKey" ! forAll { (a: Int ==>> Char, b: Byte) =>
val fSome = (k: Int, v: Char) => some((v + b).toChar)
def fNone(key: Int) = (k: Int, v: Char) => if (k == key) None else some((v + b).toChar)
val li = a.toList.map(kv => (kv._1, fSome(kv._1, kv._2).get))
a.traverseWithKey(fSome) must_=== Some(fromList(li))
a.toList.foreach { kv =>
a.traverseWithKey(fNone(kv._1)) must_=== None
}
}
}
"==>> fold" should {
"fold" in {
val f = (a: Int, b: String) => a + b.length
fromList(List(5 -> "a", 3 -> "bbb")).fold(0)((_, x, z) => f(z, x)) must_== 4
}
"foldrWithKey" in {
val f = (k: Int, a: String, result: String) => result + "(" + k.toString + ":" + a + ")"
fromList(List(5 -> "a", 3 -> "b")).foldrWithKey("Map: ")(f) must_== "Map: (5:a)(3:b)"
}
"foldMapWithKey" ! forAll { a: Byte ==>> Byte =>
val f = (i: Byte, j: Byte) => i.toInt + j.toInt
val res = a.toList.foldLeft(0: Int)((acc, kv) => acc + kv._1.toInt + kv._2.toInt)
a.foldMapWithKey(f)(intInstance) must_=== res
}
}
"==>> trim" should {
"trim sound" ! forAll { a: Int ==>> Int =>
def checkValidity(a: Int ==>> Int, lo: Option[Int], hi: Option[Int], result: Int ==>> Int) = {
val m = trim(lo, hi, a)
structurallySound(m)
m must_=== result
}
a match {
case Tip() =>
val lo = Random.nextInt()
val hi = lo + 1
checkValidity(a, Some(lo), Some(hi), Tip())
checkValidity(a, Some(lo), None , Tip())
checkValidity(a, None , Some(hi), Tip())
checkValidity(a, None , None , Tip())
case Bin(_, _, _, _) =>
def rec(m: Int ==>> Int): Unit = {
m match {
case Tip() =>
()
case Bin(k, x, l, r) =>
checkValidity(m, Some(k), None , r)
checkValidity(m, None , Some(k), l)
checkValidity(m, None , None , m)
if (k == Int.MinValue) {
checkValidity(m, Some(k), Some(k+1), Tip())
checkValidity(m, None , Some(k+1), m)
rec(r)
}
else if (k == Int.MaxValue) {
checkValidity(m, Some(k-1), Some(k), Tip())
checkValidity(m, Some(k-1), None , m)
rec(l)
}
else {
checkValidity(m, Some(k-1), Some(k+1), m)
checkValidity(m, Some(k-1), None , m)
checkValidity(m, None , Some(k+1), m)
rec(l)
rec(r)
}
}
}
rec(a)
}
}
"trimLookupLo sound" ! forAll { a: Int ==>> Int =>
def checkValidity(a: Int ==>> Int, lk: Int, hk: Option[Int]) = {
val (x, m) = trimLookupLo(lk, hk, a)
structurallySound(m)
val t1 = a.lookup(lk)
val t2 = trim(Some(lk), hk, a)
(x, m) must_=== (t1, t2)
}
a match {
case Tip() =>
val lk = Random.nextInt()
val hk = lk + 1
checkValidity(a, lk, Some(hk))
checkValidity(a, lk, None)
case Bin(_, _, _, _) =>
def rec(m: Int ==>> Int): Unit = {
m match {
case Tip() =>
()
case Bin(k, x, l, r) =>
checkValidity(m, k, None)
if (k == Int.MinValue) {
checkValidity(m, k, Some(k+1))
rec(r)
}
else if (k == Int.MaxValue) {
checkValidity(m, k-1, Some(k))
checkValidity(m, k-1, None)
rec(l)
}
else {
checkValidity(m, k-1, Some(k+1))
checkValidity(m, k-1, None)
rec(l)
rec(r)
}
}
}
rec(a)
}
}
}
"==>> list operations" should {
"values" in {
fromList(List(5 -> "a", 3 -> "b")).values must_===(List("b", "a"))
}
"keys" in {
fromList(List(5 -> "a", 3 -> "b")).keys must_===(List(3, 5))
}
"keySet" in {
fromList(List(5 -> "a", 3 -> "b")).keySet must_===(ISet.fromList(List(3, 5)))
empty[Int, String].keySet must_===(ISet.empty[Int])
}
"fromList" in {
fromList(List.empty[(Int, String)]) must_===(empty[Int, String])
fromList(List(5 -> "a", 3 -> "b", 5 -> "c")) must_===(fromList(List(5 -> "c", 3 -> "b")))
fromList(List(5 -> "c", 3 -> "b", 5 -> "a")) must_===(fromList(List(5 -> "a", 3 -> "b")))
}
"fromListWith" in {
fromListWith(List(5 -> "a", 5 -> "b", 3 -> "b", 3 -> "a", 5 -> "a"))(_ + _) must_===(fromList(List(3 -> "ab", 5 -> "aba")))
fromListWith(List.empty[(Int, String)])(_ + _) must_===(empty[Int, String])
}
"fromListWithKey" in {
val f = (k: Int, a1: String, a2: String) => k.toString + a1 + a2
fromListWithKey(List(5 -> "a", 5 -> "b", 3 -> "b", 3 -> "a", 5 -> "a"))(f) must_===(fromList(List(3 -> "3ab", 5 -> "5a5ba")))
fromListWithKey(List.empty[(Int, String)])(f) must_===(empty[Int, String])
}
"toList" in {
import std.tuple._
fromList(List(5 -> "a", 3 -> "b")).toList must_===(List(3 -> "b", 5 -> "a"))
empty[Int, String].toList must_===(List.empty[(Int, String)])
}
}
"==>> fromSet" should {
"fromSet" in {
fromSet(ISet.fromList(List[Int](3, 5))){ i: Int => List.fill(i)('a').mkString } must_=== fromList(List(5 -> "aaaaa", 3 -> "aaa"))
fromSet(ISet.fromList(List[Int]())){ i: Int => i } must_=== empty
}
"fromSet" ! forAll { (a: ISet[Int]) =>
val li = a.toList.map(i => (i, i))
fromSet(a)(i => i) must_=== fromList(li)
}
"consistent keySet" ! forAll { a: Byte ==>> Byte =>
fromSet(a.keySet)(_ => ()) must_=== a.map(_ => ())
}
}
/*"==>> validity" should {
"valid" in {
fromList(List(3 -> "b", 5 -> "a")).isValid must_== true
//-- > valid (fromAscList [(3,"b"), (5,"a")]) == True
//-- > valid (fromAscList [(5,"a"), (3,"b")]) == False
}
}*/
checkAll(order.laws[Int ==>> Int])
checkAll(monoid.laws[Int ==>> Int])
{
implicit def equMapConj[A: Equal, B: Equal]: Equal[(A ==>> B) @@ Tags.Conjunction] =
Tag.subst(implicitly)
implicit def arbMapConj[A, B](implicit a: Arbitrary[A ==>> B]
): Arbitrary[(A ==>> B) @@ Tags.Conjunction] =
Tag.subst(a)
checkAll("conjunction", semigroup.laws[(Int ==>> Int) @@ Tags.Conjunction])
}
"align" ! forAll { (a: Int ==>> String, b: Int ==>> Long) =>
import \&/._
val F = Align[Int ==>> ?]
val x = F.align(a, b)
val keysA = a.keySet
val keysB = b.keySet
x must_=== F.alignWith[String, Long, String \&/ Long](identity)(a, b)
x.keySet must_=== (keysA union keysB)
x.filter(_.isThis).keySet must_=== (keysA difference keysB)
x.filter(_.isThat).keySet must_=== (keysB difference keysA)
x.filter(_.isBoth).keySet must_=== (keysA intersection keysB)
x.filter(_.isThis) must_=== a.filterWithKey((k, _) => ! keysB.member(k)).map(This(_))
x.filter(_.isThat) must_=== b.filterWithKey((k, _) => ! keysA.member(k)).map(That(_))
x.filter(_.isBoth) must_=== a.filterWithKey((k, _) => keysB.member(k)).mapWithKey((k, v) => Both(v, b.lookup(k).get))
}
type IntMap[A] = Int ==>> A
checkAll(traverse.laws[IntMap])
checkAll(bind.laws[IntMap])
checkAll(align.laws[IntMap])
checkAll(zip.laws[IntMap])
checkAll(bifoldable.laws[==>>])
checkAll(FoldableTests.anyAndAllLazy[IntMap])
object instances {
def bind[A: Order] = Bind[A ==>> ?]
def traverse[A] = Traverse[A ==>> ?]
// checking absence of ambiguity
def functor[A: Order] = Functor[A ==>> ?]
}
}
Other Scala examples (source code examples)Here is a short list of links related to this Scala MapTest.scala source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.