Skip to content

Commit b051f09

Browse files
completeness test now also checks static methods
1 parent 4076ad1 commit b051f09

File tree

1 file changed

+67
-34
lines changed

1 file changed

+67
-34
lines changed

language-adaptors/rxjava-scala/src/test/scala/rx/lang/scala/CompletenessTest.scala

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class CompletenessTest extends JUnitSuite {
1313

1414
val unnecessary = "[considered unnecessary in Scala land]"
1515

16-
val correspondence = defaultInstanceMethodCorrespondence ++ Map(
17-
// manually added entries
16+
val correspondence = defaultMethodCorrespondence ++ Map(
17+
// manually added entries for Java instance methods
1818
"aggregate(Func2[T, T, T])" -> "reduce((U, U) => U)",
1919
"aggregate(R, Func2[R, _ >: T, R])" -> "fold(R)((R, T) => R)",
2020
"all(Func1[_ >: T, Boolean])" -> "forall(T => Boolean)",
@@ -40,11 +40,38 @@ class CompletenessTest extends JUnitSuite {
4040
"toSortedList(Func2[_ >: T, _ >: T, Integer])" -> unnecessary,
4141
"where(Func1[_ >: T, Boolean])" -> "filter(T => Boolean)",
4242
"window(Long, Long, TimeUnit)" -> "window(Duration, Duration)",
43-
"window(Long, Long, TimeUnit, Scheduler)" -> "window(Duration, Duration, Scheduler)"
43+
"window(Long, Long, TimeUnit, Scheduler)" -> "window(Duration, Duration, Scheduler)",
44+
45+
// manually added entries for Java static methods
46+
"create(OnSubscribeFunc[T])" -> "apply(Observer[T] => Subscription)",
47+
"defer(Func0[_ <: Observable[_ <: T]])" -> "defer(=> Observable[T])",
48+
"empty()" -> "apply(T*)",
49+
"error(Throwable)" -> "apply(Throwable)",
50+
"from(Array[T])" -> "apply(T*)",
51+
"from(Iterable[_ <: T])" -> "apply(T*)",
52+
"merge(Observable[_ <: T], Observable[_ <: T])" -> "merge(Observable[T])",
53+
"mergeDelayError(Observable[_ <: T], Observable[_ <: T])" -> "mergeDelayError(Observable[T])",
54+
"range(Int, Int)" -> "apply(Range)",
55+
"sequenceEqual(Observable[_ <: T], Observable[_ <: T])" -> "[use (first zip second) map (p => p._1 == p._2)]",
56+
"sequenceEqual(Observable[_ <: T], Observable[_ <: T], Func2[_ >: T, _ >: T, Boolean])" -> "[use (first zip second) map (p => equality(p._1, p._2))]",
57+
"switchDo(Observable[_ <: Observable[_ <: T]])" -> "switch",
58+
"synchronize(Observable[_ <: T])" -> "synchronize",
59+
"zip(Observable[_ <: T1], Observable[_ <: T2], Func2[_ >: T1, _ >: T2, _ <: R])" -> "[use instance method zip and map]"
4460
) ++ List.iterate("T", 9)(s => s + ", T").map(
4561
// all 9 overloads of startWith:
4662
"startWith(" + _ + ")" -> "[unnecessary because we can just use ++ instead]"
47-
).toMap
63+
).toMap ++ List.iterate("Observable[_ <: T]", 9)(s => s + ", Observable[_ <: T]").map(
64+
// concat 2-9
65+
"concat(" + _ + ")" -> "[unnecessary because we can use ++ instead]"
66+
).drop(1).toMap ++ List.iterate("T", 10)(s => s + ", T").map(
67+
// all 10 overloads of from:
68+
"from(" + _ + ")" -> "apply(T*)"
69+
).toMap ++ (3 to 9).map(i => {
70+
// zip3-9:
71+
val obsArgs = (1 to i).map(j => s"Observable[_ <: T$j], ").mkString("")
72+
val funcParams = (1 to i).map(j => s"_ >: T$j, ").mkString("")
73+
("zip(" + obsArgs + "Func" + i + "[" + funcParams + "_ <: R])", unnecessary)
74+
}).toMap
4875

4976
def removePackage(s: String) = s.replaceAll("(\\w+\\.)+(\\w+)", "$2")
5077

@@ -71,42 +98,37 @@ class CompletenessTest extends JUnitSuite {
7198
.filter(! _.contains("$extension"))
7299
}
73100

74-
def getStaticJavaMethods(className: String): Iterable[String] = {
75-
val c = Class.forName(className)
76-
for (method <- c.getMethods() if Modifier.isStatic(method.getModifiers)) yield {
77-
method.getName + method.getParameterTypes().map(_.getSimpleName()).mkString("(", ", ", ")")
78-
}
79-
}
101+
// also applicable for Java types
102+
def getPublicInstanceAndCompanionMethods(tp: Type): Iterable[String] =
103+
getPublicInstanceMethods(tp) ++
104+
getPublicInstanceMethods(tp.typeSymbol.companionSymbol.typeSignature)
80105

81-
def getObservableCompanionMethods: Iterable[String] = {
82-
val tp = typeOf[rx.lang.scala.Observable.type]
83-
getPublicInstanceMethods(tp.typeSymbol.companionSymbol.typeSignature)
84-
// TODO how can we filter out instance methods which were put into companion because
85-
// of extends AnyVal in a way which does not depend on implementation-chosen name '$extension'?
86-
.filter(! _.contains("$extension"))
87-
}
88106

89107
def printMethodSet(title: String, tp: Type) {
90108
println("\n" + title)
91109
println(title.map(_ => '-') + "\n")
92110
getPublicInstanceMethods(tp).toList.sorted.foreach(println(_))
93111
}
94112

113+
@Ignore // because spams output
95114
@Test def printJavaInstanceMethods: Unit = {
96115
printMethodSet("Instance methods of rx.Observable",
97116
typeOf[rx.Observable[_]])
98117
}
99118

119+
@Ignore // because spams output
100120
@Test def printScalaInstanceMethods: Unit = {
101121
printMethodSet("Instance methods of rx.lang.scala.Observable",
102122
typeOf[rx.lang.scala.Observable[_]])
103123
}
104124

125+
@Ignore // because spams output
105126
@Test def printJavaStaticMethods: Unit = {
106127
printMethodSet("Static methods of rx.Observable",
107128
typeOf[rx.Observable[_]].typeSymbol.companionSymbol.typeSignature)
108129
}
109130

131+
@Ignore // because spams output
110132
@Test def printScalaCompanionMethods: Unit = {
111133
printMethodSet("Companion methods of rx.lang.scala.Observable",
112134
typeOf[rx.lang.scala.Observable.type])
@@ -125,25 +147,36 @@ class CompletenessTest extends JUnitSuite {
125147
.replaceAllLiterally("_ >: ", "")
126148
.replaceAll("(\\w+)\\(\\)", "$1")
127149
}
128-
129-
def defaultInstanceMethodCorrespondence: Map[String, String] = {
130-
val instanceMethods = getPublicInstanceMethods(typeOf[rx.Observable[_]]).toList.sorted
131-
val tuples = for (javaM <- instanceMethods) yield (javaM, javaMethodSignatureToScala(javaM))
150+
151+
def defaultMethodCorrespondence: Map[String, String] = {
152+
val allMethods = getPublicInstanceAndCompanionMethods(typeOf[rx.Observable[_]])
153+
val tuples = for (javaM <- allMethods) yield (javaM, javaMethodSignatureToScala(javaM))
132154
tuples.toMap
133155
}
134156

135-
@Test def printDefaultInstanceMethodCorrespondence: Unit = {
136-
println("\nDefault Instance Method Correspondence")
137-
println( "--------------------------------------\n")
138-
val c = SortedMap(defaultInstanceMethodCorrespondence.toSeq : _*)
157+
@Ignore // because spams output
158+
@Test def printDefaultMethodCorrespondence: Unit = {
159+
println("\nDefault Method Correspondence")
160+
println( "-----------------------------\n")
161+
val c = SortedMap(defaultMethodCorrespondence.toSeq : _*)
139162
val len = c.keys.map(_.length).max + 2
140163
for ((javaM, scalaM) <- c) {
141164
println(s""" %-${len}s -> %s,""".format("\"" + javaM + "\"", "\"" + scalaM + "\""))
142165
}
143166
}
144167

168+
@Ignore // because spams output
169+
@Test def printCorrectedMethodCorrespondence: Unit = {
170+
println("\nCorrected Method Correspondence")
171+
println( "-------------------------------\n")
172+
val c = SortedMap(correspondence.toSeq : _*)
173+
for ((javaM, scalaM) <- c) {
174+
println("%s -> %s,".format("\"" + javaM + "\"", "\"" + scalaM + "\""))
175+
}
176+
}
177+
145178
def checkMethodPresence(expectedMethods: Iterable[String], tp: Type): Unit = {
146-
val actualMethods = getPublicInstanceMethods(tp).toSet
179+
val actualMethods = getPublicInstanceAndCompanionMethods(tp).toSet
147180
val expMethodsSorted = expectedMethods.toList.sorted
148181
var good = 0
149182
var bad = 0
@@ -161,7 +194,7 @@ class CompletenessTest extends JUnitSuite {
161194
println("\nTesting that all mentioned Scala methods exist")
162195
println( "----------------------------------------------\n")
163196

164-
val actualMethods = getPublicInstanceMethods(typeOf[rx.lang.scala.Observable[_]]).toSet
197+
val actualMethods = getPublicInstanceAndCompanionMethods(typeOf[rx.lang.scala.Observable[_]]).toSet
165198
var good = 0
166199
var bad = 0
167200
for ((javaM, scalaM) <- SortedMap(correspondence.toSeq :_*)) {
@@ -175,18 +208,18 @@ class CompletenessTest extends JUnitSuite {
175208
}
176209
}
177210
val status = if (bad == 0) "SUCCESS" else "BAD"
178-
println(s"$status: $bad out of ${bad+good} methods were not found in Scala Observable")
211+
println(s"\n$status: $bad out of ${bad+good} methods were not found in Scala Observable")
179212
}
180-
181-
@Ignore // because we prefer the verbose version
182-
@Test def checkScalaMethodPresence: Unit = {
183-
checkMethodPresence(correspondence.values, typeOf[rx.lang.scala.Observable[_]])
184-
}
185-
213+
186214
@Test def checkJavaMethodPresence: Unit = {
187215
println("\nTesting that all mentioned Java methods exist")
188216
println( "---------------------------------------------\n")
189217
checkMethodPresence(correspondence.keys, typeOf[rx.Observable[_]])
190218
}
191219

220+
@Ignore // because we prefer the verbose version
221+
@Test def checkScalaMethodPresence: Unit = {
222+
checkMethodPresence(correspondence.values, typeOf[rx.lang.scala.Observable[_]])
223+
}
224+
192225
}

0 commit comments

Comments
 (0)