JS backend: added tests which pass an extension lambda to native code and visa versa.

Added workarounds in some tests because Rhino wrongly implicitly converts first parameter of `Function.call` to `Object`. But it's contradicts to ES5 specification(par. 15.3.4.4).

(#KT-4238, #KT-4345) In progress
This commit is contained in:
Zalim Bashorov
2014-03-12 20:56:42 +04:00
parent 597fff45e3
commit 206be96509
7 changed files with 92 additions and 18 deletions
@@ -88,4 +88,12 @@ public final class NativeInteropTest extends SingleFileTranslationTest {
public void testNativePropertyWithCustomName() throws Exception {
checkFooBoxIsOk();
}
public void testPassExtLambdaToNative() throws Exception {
checkFooBoxIsOk();
}
public void testPassExtLambdaFromNative() throws Exception {
checkFooBoxIsOk();
}
}
@@ -1,15 +1,30 @@
package foo
fun assertEquals<T>(expected: T, actual: T, message: String) {
if (expected != actual) throw Exception("Failed when $message, expected = $expected, actual = $actual")
}
// workaround for Rhino
var n = 0
class A {
val i = ++n
}
fun box(): String {
fun Int.foo(): Boolean {
fun Int.bar() = this == 2 && this@foo == 1
val b = { this == 1 }
fun A.foo() {
fun A.bar() {
assertEquals(2, this.i, "check this.i in A.bar()")
assertEquals(1, this@foo.i, "check this@foo.i in A.bar()")
}
val b = { assertEquals(1, this.i, "check this.i in b") }
return this == 1 && 2.bar() && b()
}
assertEquals(1, this.i, "check this.i in A.foo()")
A().bar()
b()
}
if (!1.foo()) return "Failed"
A().foo()
return "OK"
return "OK"
}
@@ -1,17 +1,20 @@
// KT-2388
package foo
var done = 0
// workaround for Rhino
class Done(val i: Int)
var done = Done(0)
object foo {
var result = "FAIL"
val lambda = {
result = "foo.lambda OK"
done = 3
done = Done(3)
}
val extLambda: Int.() -> Unit = {
val extLambda: Done.() -> Unit = {
result = "foo.extLambda OK"
done = this
}
@@ -22,10 +25,10 @@ class Foo {
val lambda = {
result = "Foo::lambda OK"
done = -7
done = Done(-7)
}
val extLambda: Int.() -> Unit = {
val extLambda: Done.() -> Unit = {
result = "Foo::extLambda OK"
done = this
}
@@ -41,20 +44,20 @@ fun box(): String {
a()
if (foo.result != "foo.lambda OK") return "foo.result = \"${foo.result}\", but expected \"foo.lambda OK\""
if (done != 3) return "done = $done, but expected 3"
if (done.i != 3) return "done.i = ${done.i}, but expected 3"
23.b()
Done(23).b()
if (foo.result != "foo.extLambda OK") return "foo.result = \"${foo.result}\", but expected \"foo.extLambda OK\""
if (done != 23) return "done = $done, but expected 23"
if (done.i != 23) return "done.i = ${done.i}, but expected 23"
c()
if (f.result != "Foo::lambda OK") return "a.result = \"${f.result}\", but expected \"Foo::lambda OK\""
if (done != -7) return "done = $done, but expected -7"
if (done.i != -7) return "done.i = ${done.i}, but expected -7"
71.d()
Done(71).d()
if (f.result != "Foo::extLambda OK") return "a.result = \"${f.result}\", but expected \"Foo::extLambda OK\""
if (done != 71) return "done = $done, but expected 71"
if (done.i != 71) return "done.i = ${done.i}, but expected 71"
return "OK"
}
@@ -0,0 +1,18 @@
package foo
native
class A(val v: String)
class B {
fun bar(a: A, extLambda: A.(Int, String) -> String): String = a.extLambda(7, "_rr_")
}
native
fun nativeBox(b: B): String = noImpl
fun box(): String {
val r = nativeBox(B())
if (r != "foo_rr_7") return r
return "OK"
}
@@ -0,0 +1,16 @@
package foo
native
class A(val v: String)
native
fun bar(a: A, extLambda: A.(Int, String) -> String): String = noImpl
fun box(): String {
val a = A("test")
val r = bar(a) { i, s -> "${this.v} $i $s"}
if (r != "test 4 boo") return r
return "OK"
}
@@ -0,0 +1,7 @@
function A(v) {
this.v = v;
}
function nativeBox(b) {
return b.bar(new A("foo"), function(i, s) { return "" + this.v + s + i })
}
@@ -0,0 +1,7 @@
function A(v) {
this.v = v;
}
function bar(a, extLambda) {
return extLambda.call(a, 4, "boo")
}