Skip to content

Commit ef81130

Browse files
bakeemawaytoysjbgi
authored andcommitted
Added unit test coverage for Semigroup implementations. The StringBuffer and StringBuilder tests fail because both of those types are mutable. The IO test fails because the ArbitraryIO implementation does not implement equals.
1 parent 405c3ec commit ef81130

2 files changed

Lines changed: 174 additions & 0 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package fj.data
2+
3+
import org.scalacheck.Arbitrary
4+
5+
/**
6+
*
7+
*/
8+
object ArbitraryIO {
9+
10+
implicit def arbitraryIO[T](implicit arbT: Arbitrary[T]): Arbitrary[IO[T]] =
11+
Arbitrary(arbT.arbitrary.map(t => new IO[T]() {
12+
13+
override def run(): T = t
14+
15+
override def toString: String = t.toString
16+
17+
override def hashCode(): Int = t.hashCode()
18+
19+
override def equals(obj: scala.Any): Boolean = ???
20+
}))
21+
22+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package fj
2+
3+
import fj.ArbitraryP._
4+
import fj.ArbitraryUnit.arbitraryUnit
5+
import fj.Ord.intOrd
6+
import fj.data.ArbitraryArray.arbitraryArray
7+
import fj.data.ArbitraryIO.arbitraryIO
8+
import fj.data.ArbitraryList.arbitraryList
9+
import fj.data.ArbitraryNatural.arbitraryNatural
10+
import fj.data.ArbitraryNonEmptyList.arbitraryNonEmptyList
11+
import fj.data.ArbitraryOption.arbitraryOption
12+
import fj.data.ArbitrarySet.arbitrarySet
13+
import fj.data.ArbitraryStream.arbitraryStream
14+
import org.scalacheck.Arbitrary._
15+
import org.scalacheck.Prop._
16+
import org.scalacheck.{Arbitrary, Properties}
17+
18+
/**
19+
* Scalacheck [[Properties]] for [[Semigroup]] implementations.
20+
*
21+
* @param s a Semigroup implementation.
22+
* @param desc a description of the Semigroup implementation.
23+
* @param arbitrary a Scalacheck [[Arbitrary]] implementation for the Semigroup's type.
24+
* @tparam T the type to which the Semigroup applies.
25+
*/
26+
case class SemigroupProperties[T](s: Semigroup[T], desc: String)(implicit val arbitrary: Arbitrary[T]) extends Properties(desc) {
27+
28+
29+
property("sum(x,y)") = forAll((x: T, y: T, z: T) =>
30+
s.sum(s.sum(x, y), z) == s.sum(x, s.sum(y, z)))
31+
32+
property("sum()") = forAll((x: T, y: T, z: T) => {
33+
val sf = s.sum()
34+
sf.f(sf.f(x).f(y)).f(z) == sf.f(x).f(sf.f(y).f(z))
35+
})
36+
37+
property("dual()") = forAll((x: T, y: T, z: T) => {
38+
val sd = s.dual()
39+
sd.sum(sd.sum(x, y), z) == sd.sum(x, sd.sum(y, z))
40+
})
41+
42+
property("sum(x)") = forAll((x: T, y: T) =>
43+
s.sum(x).f(y) == s.sum(x, y))
44+
45+
}
46+
47+
48+
/**
49+
*
50+
*/
51+
object CheckSemigroup extends Properties("Semigroup") {
52+
53+
54+
def idInt(n: Int): java.lang.Integer = n
55+
56+
implicit def oi: Ord[Int] = intOrd.contramap(idInt _)
57+
58+
implicit lazy val arbJavaBigDecimal: Arbitrary[java.math.BigDecimal] = Arbitrary(
59+
Arbitrary.arbLong.arbitrary.map(l => new java.math.BigDecimal(l))
60+
)
61+
62+
implicit lazy val arbJavaBigInteger: Arbitrary[java.math.BigInteger] = Arbitrary(
63+
Arbitrary.arbBigInt.arbitrary.map(_.bigInteger)
64+
)
65+
66+
implicit lazy val arbJavaInteger: Arbitrary[Integer] = Arbitrary(
67+
Arbitrary.arbInt.arbitrary.map(i => i)
68+
)
69+
70+
implicit lazy val arbJavaLong: Arbitrary[java.lang.Long] = Arbitrary(
71+
Arbitrary.arbLong.arbitrary.map(i => i)
72+
)
73+
74+
implicit lazy val arbJavaBoolean: Arbitrary[java.lang.Boolean] = Arbitrary(
75+
Arbitrary.arbBool.arbitrary.map(b => b)
76+
)
77+
78+
implicit lazy val arbStringBuilder: Arbitrary[java.lang.StringBuilder] = Arbitrary(
79+
Arbitrary.arbString.arbitrary.map(new java.lang.StringBuilder(_))
80+
)
81+
82+
implicit lazy val arbStringBuffer: Arbitrary[StringBuffer] = Arbitrary(
83+
Arbitrary.arbString.arbitrary.map(new StringBuffer(_))
84+
)
85+
86+
include(SemigroupProperties(Semigroup.arraySemigroup[Int](), "arraySemigroup()"))
87+
88+
include(SemigroupProperties(Semigroup.bigdecimalAdditionSemigroup, "bigdecimalAdditionSemigroup"))
89+
include(SemigroupProperties(Semigroup.bigdecimalMultiplicationSemigroup, "bigdecimalMultiplicationSemigroup"))
90+
include(SemigroupProperties(Semigroup.bigDecimalMaximumSemigroup, "bigDecimalMaximumSemigroup"))
91+
include(SemigroupProperties(Semigroup.bigDecimalMinimumSemigroup, "bigDecimalMinimumSemigroup"))
92+
93+
include(SemigroupProperties(Semigroup.bigintAdditionSemigroup, "bigintAdditionSemigroup"))
94+
include(SemigroupProperties(Semigroup.bigintMultiplicationSemigroup, "bigintMultiplicationSemigroup"))
95+
include(SemigroupProperties(Semigroup.bigintMaximumSemigroup, "bigintMaximumSemigroup"))
96+
include(SemigroupProperties(Semigroup.bigintMinimumSemigroup, "bigintMinimumSemigroup"))
97+
98+
include(SemigroupProperties(Semigroup.conjunctionSemigroup, "conjunctionSemigroup"))
99+
include(SemigroupProperties(Semigroup.disjunctionSemigroup, "disjunctionSemigroup"))
100+
include(SemigroupProperties(Semigroup.exclusiveDisjunctionSemiGroup, "exclusiveDisjunctionSemiGroup"))
101+
102+
include(SemigroupProperties(Semigroup.firstOptionSemigroup[Int](), "firstOptionSemigroup()"))
103+
include(SemigroupProperties(Semigroup.firstSemigroup[Int](), "firstSemigroup()"))
104+
105+
include(SemigroupProperties(Semigroup.intAdditionSemigroup, "intAdditionSemigroup"))
106+
include(SemigroupProperties(Semigroup.intMultiplicationSemigroup, "intMultiplicationSemigroup"))
107+
include(SemigroupProperties(Semigroup.intMaximumSemigroup, "intMaximumSemigroup"))
108+
include(SemigroupProperties(Semigroup.intMinimumSemigroup, "intMinimumSemigroup"))
109+
110+
include(SemigroupProperties(Semigroup.ioSemigroup[String](Semigroup.stringSemigroup), "ioSemigroup(Semigroup)"))
111+
112+
include(SemigroupProperties(Semigroup.lastOptionSemigroup[Int](), "lastOptionSemigroup()"))
113+
include(SemigroupProperties(Semigroup.lastSemigroup[Int](), "lastSemigroup()"))
114+
115+
include(SemigroupProperties(Semigroup.longAdditionSemigroup, "longAdditionSemigroup"))
116+
include(SemigroupProperties(Semigroup.longMultiplicationSemigroup, "longMultiplicationSemigroup"))
117+
include(SemigroupProperties(Semigroup.longMaximumSemigroup, "longMaximumSemigroup"))
118+
include(SemigroupProperties(Semigroup.longMinimumSemigroup, "longMinimumSemigroup"))
119+
120+
121+
include(SemigroupProperties(Semigroup.listSemigroup[Int], "listSemigroup"))
122+
123+
include(SemigroupProperties(Semigroup.naturalAdditionSemigroup, "naturalAdditionSemigroup"))
124+
include(SemigroupProperties(Semigroup.naturalMaximumSemigroup, "naturalMaximumSemigroup"))
125+
include(SemigroupProperties(Semigroup.naturalMinimumSemigroup, "naturalMinimumSemigroup"))
126+
include(SemigroupProperties(Semigroup.naturalMultiplicationSemigroup, "naturalMultiplicationSemigroup"))
127+
128+
include(SemigroupProperties(Semigroup.nonEmptyListSemigroup[Int], "nonEmptyListSemigroup"))
129+
130+
include(SemigroupProperties(Semigroup.p1Semigroup(Semigroup.intAdditionSemigroup), "p1Semigroup(Semigroup<A>)"))
131+
include(SemigroupProperties(Semigroup.p2Semigroup(Semigroup.intAdditionSemigroup, Semigroup.stringSemigroup), "p2Semigroup(Semigroup<A>,Semigroup<B>)"))
132+
133+
include(SemigroupProperties(Semigroup.semigroup[Int](new F2[Int, Int, Int] {
134+
def f(x: Int, y: Int): Int = x + y
135+
}), "semigroup(F<A,A,A>)"))
136+
137+
include(SemigroupProperties(Semigroup.semigroup[Int](new F[Int, F[Int, Int]] {
138+
def f(x: Int): F[Int, Int] = (y: Int) => x + y
139+
}), "semigroup(F<A,F<A,A>>)"))
140+
141+
include(SemigroupProperties(Semigroup.setSemigroup[Int](), "setSemigroup()"))
142+
include(SemigroupProperties(Semigroup.streamSemigroup[Int](), "streamSemigroup"))
143+
144+
include(SemigroupProperties(Semigroup.stringSemigroup, "stringSemigroup"))
145+
include(SemigroupProperties(Semigroup.stringBufferSemigroup, "stringBufferSemigroup"))
146+
include(SemigroupProperties(Semigroup.stringBuilderSemigroup, "stringBuilderSemigroup"))
147+
148+
149+
include(SemigroupProperties(Semigroup.unitSemigroup, "unitSemigroup"))
150+
151+
152+
}

0 commit comments

Comments
 (0)