JS backend: added more tests for closures.

This commit is contained in:
Zalim Bashorov
2014-02-26 16:04:33 +04:00
parent ec71a90394
commit a48dc25c46
18 changed files with 518 additions and 5 deletions
@@ -52,7 +52,15 @@ public final class ClosureTest extends SingleFileTranslationTest {
fooBoxTest();
}
public void testSimpleRecursion() throws Exception {
public void testRecursiveFunction() throws Exception {
checkFooBoxIsOk();
}
public void testRecursiveFunctionWithSameNameDeclaration() throws Exception {
checkFooBoxIsOk();
}
public void testRecursiveExtFunction() throws Exception {
checkFooBoxIsOk();
}
@@ -64,8 +72,7 @@ public final class ClosureTest extends SingleFileTranslationTest {
checkFooBoxIsOk();
}
// TODO: fix
public void igonre_testClosureLocalFunctionByInnerFunctionInConstrunctor() throws Exception {
public void testClosureLocalFunctionByInnerFunctionInConstructor() throws Exception {
checkFooBoxIsOk();
}
@@ -84,4 +91,56 @@ public final class ClosureTest extends SingleFileTranslationTest {
public void testClosureLocalLiteralFunction() throws Exception {
checkFooBoxIsOk();
}
public void testClosureThisInLocalFunction() throws Exception {
checkFooBoxIsOk();
}
public void testClosureValToScopeWithSameNameDeclaration() throws Exception {
checkFooBoxIsOk();
}
public void testClosureVarToScopeWithSameNameDeclaration() throws Exception {
checkFooBoxIsOk();
}
public void testClosureLocalInNestedObject() throws Exception {
checkFooBoxIsOk();
}
public void testClosureThisAndReceiver() throws Exception {
checkFooBoxIsOk();
}
public void testClosureGenericTypeValue() throws Exception {
checkFooBoxIsOk();
}
public void testClosureInObject() throws Exception {
checkFooBoxIsOk();
}
public void testWithManyClosuresInNestedFunctionsAndObjects() throws Exception {
checkFooBoxIsOk();
}
public void testClosureReceiverInLocalExtFunByLocalExtFun() throws Exception {
checkFooBoxIsOk();
}
public void testClosureArrayListInstance() throws Exception {
checkFooBoxIsOk();
}
public void testClosureThisByUsingMethodFromParentClass() throws Exception {
checkFooBoxIsOk();
}
public void testClosureThisInFunctionWhichNamedSameAsParentClass() throws Exception {
checkFooBoxIsOk();
}
public void testClosureInFewFunctionWithDifferentName() throws Exception {
checkFooBoxIsOk();
}
}
@@ -0,0 +1,27 @@
package foo
import java.util.ArrayList
fun test(f: () -> String): String {
val funLit = { f() }
return funLit()
}
fun box(): String {
val l = ArrayList<String>()
l.add("1 ")
l.add("foobar ")
l.add("baz")
val f = {
var s = ""
for (e in l) s += e
s
}
val r = f()
if (r != "1 foobar baz") return "$r"
return "OK"
}
@@ -0,0 +1,18 @@
package foo
class A<T>(val a: T) {
val foo = { a }
}
fun <T> T.bar() = { this }
fun assertEquals(expected: String, actual: String) {
if (expected != actual) throw Exception("Expected: $expected, actual: $actual")
}
fun box(): String {
assertEquals("ok", A("ok").foo())
assertEquals("a42", "a42".bar()())
return "OK"
}
@@ -0,0 +1,33 @@
package foo
fun box(): String {
val bar = 12
val baz = {
var result = "test1 "
if (true) {
val bar = "some text"
result += bar
}
result += bar
result
}
val r1 = baz()
if (r1 != "test1 some text12") return "r1 = $r1";
val boo = {
var result = "test2 "
result += bar
if (true) {
val bar = 4
result += bar
}
result
}
val r2 = boo()
if (r2 != "test2 124") return "r2 = $r2";
return "OK"
}
@@ -0,0 +1,27 @@
package foo
object A {
val a = 1
fun foo() = 31
val f = { a + foo() }
}
class B {
class object {
val a = 21
fun foo() = 3
val f = { this.a + this.foo() }
}
}
fun box(): String {
val a = A.f()
if (a != 32) return "a != 32, a = $a"
val b = B.f()
if (b != 24) return "b != 24, b = $b"
return "OK"
}
@@ -0,0 +1,13 @@
package foo
fun box(): String {
var boo = "OK"
var foo = object {
object bar {
val baz = boo
}
}
return foo.bar.baz
}
@@ -0,0 +1,15 @@
package foo
fun box(): String {
fun Int.foo(): Boolean {
fun Int.bar() = this == 2 && this@foo == 1
val b = { this == 1 }
return this == 1 && 2.bar() && b()
}
if (!1.foo()) return "Failed"
return "OK"
}
@@ -3,15 +3,27 @@ package foo
class A() {
var i = 0
fun boo() = 1
fun f() {
for (j in 0..2) {
foo {
i += j
i += j + boo()
}
}
}
}
fun A.bar(): Int {
for (u in 4..7) {
foo {
i += u + boo()
}
}
return i
}
fun foo(f: () -> Unit) {
f()
}
@@ -19,5 +31,5 @@ fun foo(f: () -> Unit) {
fun box(): Boolean {
val a = A()
a.f()
return a.i == 3
return a.i == 6 && a.bar() == 32
}
@@ -0,0 +1,39 @@
package foo
class A(val a: String) {
fun A.foo() = { a + this.a + this@foo.a + this@A.a }()
fun bar(a: A) = this.foo() + " " + a.foo()
fun A.boo() = { array(this, this@boo, this@A) }()
fun baz(a: A) = this.boo().stringify() + " " + a.boo().stringify()
fun Array<A>.stringify(): String {
var result = ""
for (a in this) {
result += a.a
}
return result
}
}
fun assertEquals(expected: String, actual: String) {
if (expected != actual) throw Exception("Expected: $expected, actual: $actual")
}
fun box(): String {
val a = A("a")
val b = A("b")
assertEquals("aaaa aaaa", a.bar(a))
assertEquals("aaaa bbba", a.bar(b))
assertEquals("bbbb aaab", b.bar(a))
assertEquals("bbbb bbbb", b.bar(b))
assertEquals("aaa aaa", a.baz(a))
assertEquals("aaa bba", a.baz(b))
assertEquals("bbb aab", b.baz(a))
assertEquals("bbb bbb", b.baz(b))
return "OK"
}
@@ -0,0 +1,61 @@
package foo
// HACKS
native
val ROOT = "Kotlin.modules.JS_TESTS"
native
val PATH_TO_F_CREATOR = "foo.B.B\$f"
native
val PATH_TO_G_CREATOR = "foo.B.B\$f_0"
native("$ROOT.$PATH_TO_F_CREATOR")
val F_CREATOR: Any = noImpl
native("$ROOT.$PATH_TO_G_CREATOR")
val G_CREATOR: Any = noImpl
// Test
open class A {
fun foo() = "A::foo"
}
class B : A() {
fun boo() = "B::boo"
val f = { foo() }
val g = { boo() }
}
fun box(): String {
val b = B()
val f = b.f
val g = b.g
assertEquals("A::foo", f())
assertEquals("B::boo", g())
val fs = F_CREATOR.toString()
val gs = G_CREATOR.toString().replaceAll("boo", "foo")
assertEquals(gs, fs)
return "OK"
}
// Helpers
fun assertEquals<T>(expected: T, actual: T) {
if (expected != actual) throw Exception("expected: $expected, actual: $actual");
}
native
fun String.replace(regexp: RegExp, replacement: String): String = noImpl
fun String.replaceAll(regexp: String, replacement: String): String = replace(RegExp(regexp, "g"), replacement)
native
class RegExp(regexp: String, flags: String)
@@ -0,0 +1,19 @@
package foo
class B(val b: String)
class A(val a: String) {
fun B.A() = { a + b }
fun foo(a: B) = a.A()()
}
fun box(): String {
val bar = A("bar")
val baz = B("baz")
val r = bar.foo(baz)
if (r != "barbaz") return "$r";
return "OK"
}
@@ -0,0 +1,22 @@
package foo
class Foo {
val o = "O"
val k = "K"
fun test(): String {
fun bar() = o
fun Int.baz() = k + this
val boo = { k }
val cux: Int.()->String = { o + this }
return bar() + 17.baz() + 23.cux() + boo()
}
}
fun box(): String {
val a = Foo().test()
if (a != "OK17O23K") return "$a"
return "OK"
}
@@ -0,0 +1,30 @@
package foo
val f = true
fun box(): String {
val bar = "test "
val boo = "another "
fun baz(): String {
var result = bar
if (f) {
val bar = 42
result += bar
val boo = 7
result += boo
}
result += boo
result += bar
return result
}
val r = baz()
if (r != "test 427another test ") return r;
return "OK"
}
@@ -0,0 +1,31 @@
package foo
val f = true
fun box(): String {
var bar = ""
var boo = 23
fun baz() {
bar += "test "
if (f) {
val v1 = 42
var bar = 12
bar += v1
val v2 = 7
var boo = ""
boo += v2
}
boo += 7
bar += "text"
}
baz()
if (bar != "test text") return "bar != \"test text\", bar = \"$bar\"";
if (boo != 30) return "boo != 61, boo = $boo";
return "OK"
}
@@ -0,0 +1,39 @@
package foo
fun Int.foo(a: Int): Int {
if (a == 0) {
return this.foo(4) + foo(7) + this
}
return a
}
fun assertEquals<T>(expected: T, actual: T) {
if (expected != actual) throw Exception("expected: $expected, actual, $actual")
}
fun box(): String {
assertEquals(34, 23.foo(0))
fun Int.bar(a: Int): Int {
if (a == 0) {
return this.bar(12) + bar(4) + this
}
return a
}
assertEquals(19, 3.bar(0))
fun f() = 11
val v = 3
fun Int.baz(a: Int): Int {
if (a == 0) {
return this.baz(v) + baz(f()) + this
}
return a
}
assertEquals(21, 7.baz(0))
return "OK"
}
@@ -0,0 +1,43 @@
package foo
fun bar(i: Int = 0): Int {
if (i == 7) {
val bar = i
return bar
}
else {
return bar(i - 1)
}
}
fun box(): String {
val a = bar(10)
if (a != 7) return "bar(10) = $a, but expected 7"
fun boo(i: Int = 0): Int {
if (i == 4) {
val boo = i
return boo
} else {
return boo(i - 1)
}
}
val b = boo(17)
if (b != 4) return "boo(17) = $b, but expected 4"
fun f() = 1
val v = 3
fun baz(i: Int = 0): Int {
if (i == v) {
val baz = f() + v
return baz
} else {
return baz(i - 1)
}
}
val c = baz(10)
if (c != 4) return "baz(10) = $c, but expected 4"
return "OK"
}
@@ -0,0 +1,25 @@
package foo
fun run<T>(f: ()->T) = f()
fun box(): String {
val t = run {
object {
fun foo() = "3"
fun boo(param: String): String {
val a = object {
fun bar() = "57"
fun b(): String = run { param + bar() + foo() }
}
return a.b()
}
}
}
val r = t.boo("OK")
if (r != "OK573") return "r != \"OK573\", r = \"$r\""
return "OK"
}