JS: add coroutines tests

This commit is contained in:
Alexey Andreev
2016-11-08 18:34:02 +03:00
parent 2cc299fb40
commit eae0ceed86
13 changed files with 590 additions and 8 deletions
@@ -0,0 +1,50 @@
// WITH_RUNTIME
class Controller {
var result = ""
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
c.resume(value)
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
fun box(): String {
val value = builder {
try {
outer@for (x in listOf("A", "B")) {
try {
result += suspendWithResult(x)
for (y in listOf("C", "D")) {
try {
result += suspendWithResult(y)
if (y == "D") {
break@outer
}
}
finally {
result += "!"
}
result += "E"
}
}
finally {
result += "@"
}
result += "ignore"
}
}
finally {
result += "finally"
}
result += "."
}
if (value != "AC!ED!@finally.") return "fail: $value"
return "OK"
}
@@ -0,0 +1,47 @@
// WITH_RUNTIME
class Controller {
var result = ""
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
c.resume(value)
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
fun box(): String {
var value = builder {
outer@for (x in listOf("O", "K")) {
result += suspendWithResult(x)
for (y in listOf("Q", "W")) {
result += suspendWithResult(y)
if (y == "W") {
break@outer
}
}
}
result += "."
}
if (value != "OQW.") return "fail: break outer loop: $value"
value = builder {
for (x in listOf("O", "K")) {
result += suspendWithResult(x)
for (y in listOf("Q", "W")) {
if (y == "W") {
break
}
result += suspendWithResult(y)
}
}
result += "."
}
if (value != "OQKQ.") return "fail: break inner loop: $value"
return "OK"
}
@@ -0,0 +1,38 @@
// WITH_RUNTIME
class Controller {
var result = ""
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
c.resume(value)
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
fun box(): String {
var value = builder {
var x = 1
do {
result += x
} while (suspendWithResult(x++) < 3)
result += "."
}
if (value != "123.") return "fail: suspend as do..while condition: $value"
value = builder {
var x = 1
do {
result += suspendWithResult(x)
result += ";"
} while (x++ < 3)
result += "."
}
if (value != "1;2;3;.") return "fail: suspend in do..while body: $value"
return "OK"
}
@@ -0,0 +1,27 @@
// WITH_RUNTIME
class Controller {
var result = ""
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
c.resume(value)
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
fun box(): String {
val value = builder {
for (x in listOf("O", "K")) {
result += suspendWithResult(x)
}
result += "."
}
if (value != "OK.") return "fail: suspend in for body: $value"
return "OK"
}
@@ -0,0 +1,72 @@
// WITH_RUNTIME
class Controller {
var result = ""
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
c.resume(value)
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
fun box(): String {
var value = builder {
if (suspendWithResult(true)) {
result = "OK"
}
}
if (value != "OK") return "fail: suspend as if condition: $value"
value = builder {
for (x in listOf(true, false)) {
if (x) {
result += suspendWithResult("O")
}
else {
result += "K"
}
}
}
if (value != "OK") return "fail: suspend in then branch: $value"
value = builder {
for (x in listOf(true, false)) {
if (x) {
result += "O"
}
else {
result += suspendWithResult("K")
}
}
}
if (value != "OK") return "fail: suspend in else branch: $value"
value = builder {
for (x in listOf(true, false)) {
if (x) {
result += suspendWithResult("O")
}
else {
result += suspendWithResult("K")
}
}
}
if (value != "OK") return "fail: suspend in both branches: $value"
value = builder {
for (x in listOf(true, false)) {
if (x) {
result += suspendWithResult("O")
}
result += ";"
}
}
if (value != "O;;") return "fail: suspend in then branch without else: $value"
return "OK"
}
@@ -0,0 +1,40 @@
// WITH_RUNTIME
class Controller {
var result = ""
suspend fun <T> suspendAndLog(value: T, c: Continuation<T>) {
result += "suspend($value);"
c.resume(value)
}
operator fun handleResult(value: String, c: Continuation<Nothing>) {
result += "return($value);"
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
fun <T> id(value: T) = value
fun box(): String {
val value = builder {
try {
if (id(23) == 23) {
return@builder suspendAndLog("OK")
}
}
finally {
result += "finally;"
}
result += "afterFinally;"
"shouldNotReach"
}
if (value != "suspend(OK);finally;return(OK);") return "fail: $value"
return "OK"
}
@@ -0,0 +1,38 @@
// WITH_RUNTIME
class Controller {
var result = ""
suspend fun <T> suspendWithResult(value: T, c: Continuation<T>) {
c.resume(value)
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.result
}
fun box(): String {
var value = builder {
var x = 1
while (suspendWithResult(x) <= 3) {
result += x++
}
result += "."
}
if (value != "123.") return "fail: suspend as while condition: $value"
value = builder {
var x = 1
while (x <= 3) {
result += suspendWithResult(x++)
result += ";"
}
result += "."
}
if (value != "1;2;3;.") return "fail: suspend in while body: $value"
return "OK"
}
@@ -0,0 +1,26 @@
class Controller {
var log = ""
suspend fun <T> suspendAndLog(value: T, x: Continuation<T>) {
log += "suspend($value);"
x.resume(value)
}
operator fun handleResult(value: String, y: Continuation<Nothing>) {
log += "return($value);"
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
val controller = Controller()
c(controller).resume(Unit)
return controller.log
}
fun box(): String {
val result = builder { suspendAndLog("OK") }
if (result != "suspend(OK);return(OK);") return "fail: $result"
return "OK"
}
@@ -0,0 +1,27 @@
// MODULE: controller
// FILE: controller.kt
package lib
class Controller {
suspend fun suspendHere(x: Continuation<String>) {
x.resume("OK")
}
}
// MODULE: main(controller)
// FILE: main.kt
import lib.*
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
c(Controller()).resume(Unit)
}
fun box(): String {
var result = ""
builder {
result = suspendHere()
}
return result
}
@@ -0,0 +1,57 @@
// MODULE: controller
// FILE: controller.kt
package lib
@AllowSuspendExtensions
class Controller {
suspend fun String.suspendHere(x: Continuation<String>) {
x.resume(this)
}
inline suspend fun String.inlineSuspendHere(x: Continuation<String>) {
suspendHere(x)
}
}
suspend fun Controller.suspendExtension(v: String, x: Continuation<String>) {
v.suspendHere(x)
}
inline suspend fun Controller.inlineSuspendExtension(v: String, x: Continuation<String>) {
v.inlineSuspendHere(x)
}
// MODULE: main(controller)
// FILE: main.kt
import lib.*
suspend fun Controller.localSuspendExtension(v: String, x: Continuation<String>) {
v.suspendHere(x)
}
inline suspend fun Controller.localInlineSuspendExtension(v: String, x: Continuation<String>) {
v.inlineSuspendHere(x)
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
c(Controller()).resume(Unit)
}
fun box(): String {
var result = ""
builder {
if ("56".suspendHere() != "56") throw RuntimeException("fail 1")
if ("28".inlineSuspendHere() != "28") throw RuntimeException("fail 2")
if (suspendExtension("123") != "123") throw RuntimeException("fail 3")
if (inlineSuspendExtension("234") != "234") throw RuntimeException("fail 4")
if (localSuspendExtension("9123") != "9123") throw RuntimeException("fail 5")
if (localInlineSuspendExtension("9234") != "9234") throw RuntimeException("fail 6")
result = "OK"
}
return result
}