Report argument number mismatch nicely on wrong 'call()' invocation

The default Java reflection message in such case is not very helpful: "wrong
number of arguments"
This commit is contained in:
Alexander Udalov
2015-08-04 19:39:09 +03:00
parent 9c522b4d49
commit 3091f2af3b
4 changed files with 174 additions and 45 deletions
@@ -0,0 +1,98 @@
import kotlin.platform.platformStatic as static
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.KCallable
var foo: String = ""
class A(private var bar: String = "") {
fun getBar() = A::bar
}
object O {
private static var baz: String = ""
static fun getBaz() = O::baz.apply { isAccessible = true }
}
fun check(callable: KCallable<*>, vararg args: Any?) {
val expected = callable.parameters.size()
val actual = args.size()
if (expected == actual) {
throw AssertionError("Bad test case: expected and actual number of arguments should differ (was $expected vs $actual)")
}
val expectedExceptionMessage = "Callable expects $expected arguments, but $actual were provided."
try {
callable.call(*args)
throw AssertionError("Fail: an IllegalArgumentException should have been thrown")
} catch (e: IllegalArgumentException) {
if (e.getMessage() != expectedExceptionMessage) {
// This most probably means that we don't check number of passed arguments in reflection
// and the default check from Java reflection yields an IllegalArgumentException, but with a not that helpful message
throw AssertionError("Fail: an exception with an unrecognized message was thrown: \"${e.getMessage()}\"" +
"\nExpected message was: $expectedExceptionMessage")
}
}
}
fun box(): String {
check(::box, null)
check(::box, "")
check(::A)
check(::A, null, "")
check(O::getBaz)
check(O::getBaz, null, "")
val f = ::foo
check(f, null)
check(f, null, null)
check(f, arrayOf<Any?>(null))
check(f, "")
check(f.getter, null)
check(f.getter, null, null)
check(f.getter, arrayOf<Any?>(null))
check(f.getter, "")
check(f.setter)
check(f.setter, null, null)
check(f.setter, null, "")
val b = A().getBar()
check(b)
check(b, null, null)
check(b, "", "")
check(b.getter)
check(b.getter, null, null)
check(b.getter, "", "")
check(b.setter)
check(b.setter, null)
check(b.setter, "")
val z = O.getBaz()
check(z)
check(z, null, null)
check(z, "", "")
check(z.getter)
check(z.getter, null, null)
check(z.getter, "", "")
check(z.setter)
check(z.setter, null)
check(z.setter, "")
return "OK"
}