blob: a9684c44b5e9428fdcce1fba711540acd3f65ce8 [file] [log] [blame]
Roman Elizarovf16fd272017-02-07 11:26:00 +03001/*
2 * Copyright 2016-2017 JetBrains s.r.o.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030017package kotlinx.coroutines.experimental
18
19import org.junit.Test
20import java.io.IOException
Roman Elizarov12f961d2017-02-06 15:44:03 +030021import org.junit.Assert.*
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030022
Roman Elizarov32d95322017-02-09 15:57:31 +030023class AsyncTest : TestBase() {
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030024 @Test
25 fun testSimple(): Unit = runBlocking {
26 expect(1)
Roman Elizarov32d95322017-02-09 15:57:31 +030027 val d = async(context) {
Roman Elizarov7cf452e2017-01-29 21:58:33 +030028 expect(3)
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030029 42
30 }
Roman Elizarov7cf452e2017-01-29 21:58:33 +030031 expect(2)
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030032 check(d.isActive)
33 check(d.await() == 42)
34 check(!d.isActive)
Roman Elizarov7cf452e2017-01-29 21:58:33 +030035 expect(4)
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030036 check(d.await() == 42) // second await -- same result
Roman Elizarov7cf452e2017-01-29 21:58:33 +030037 finish(5)
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030038 }
39
Roman Elizarov4b0ef7b2017-04-17 12:39:29 +030040 @Test
41 fun testUndispatched(): Unit = runBlocking {
42 expect(1)
43 val d = async(context, start = CoroutineStart.UNDISPATCHED) {
44 expect(2)
45 42
46 }
47 expect(3)
48 check(!d.isActive)
49 check(d.await() == 42)
50 finish(4)
51 }
52
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030053 @Test(expected = IOException::class)
54 fun testSimpleException(): Unit = runBlocking {
55 expect(1)
Roman Elizarov32d95322017-02-09 15:57:31 +030056 val d = async(context) {
Roman Elizarov7cf452e2017-01-29 21:58:33 +030057 finish(3)
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030058 throw IOException()
59 }
Roman Elizarov7cf452e2017-01-29 21:58:33 +030060 expect(2)
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030061 d.await() // will throw IOException
62 }
63
64 @Test(expected = IOException::class)
65 fun testDeferAndYieldException(): Unit = runBlocking {
66 expect(1)
Roman Elizarov32d95322017-02-09 15:57:31 +030067 val d = async(context) {
Roman Elizarov7cf452e2017-01-29 21:58:33 +030068 expect(3)
69 yield() // no effect, parent waiting
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030070 finish(4)
71 throw IOException()
72 }
Roman Elizarov7cf452e2017-01-29 21:58:33 +030073 expect(2)
Roman Elizarov41c5c8b2017-01-25 13:37:15 +030074 d.await() // will throw IOException
75 }
Roman Elizarovdaa79222017-01-26 11:31:31 +030076
77 @Test
78 fun testDeferWithTwoWaiters() = runBlocking {
79 expect(1)
Roman Elizarov32d95322017-02-09 15:57:31 +030080 val d = async(context) {
Roman Elizarov7cf452e2017-01-29 21:58:33 +030081 expect(5)
Roman Elizarovdaa79222017-01-26 11:31:31 +030082 yield()
Roman Elizarov7cf452e2017-01-29 21:58:33 +030083 expect(9)
Roman Elizarovdaa79222017-01-26 11:31:31 +030084 42
85 }
Roman Elizarov7cf452e2017-01-29 21:58:33 +030086 expect(2)
Roman Elizarovdaa79222017-01-26 11:31:31 +030087 launch(context) {
88 expect(6)
89 check(d.await() == 42)
Roman Elizarov7cf452e2017-01-29 21:58:33 +030090 expect(11)
Roman Elizarovdaa79222017-01-26 11:31:31 +030091 }
Roman Elizarov7cf452e2017-01-29 21:58:33 +030092 expect(3)
93 launch(context) {
94 expect(7)
95 check(d.await() == 42)
96 expect(12)
97 }
98 expect(4)
Roman Elizarov32d95322017-02-09 15:57:31 +030099 yield() // this actually yields control to async, which produces results and resumes both waiters (in order)
Roman Elizarov7cf452e2017-01-29 21:58:33 +0300100 expect(8)
101 yield() // yield again to "d", which completes
102 expect(10)
103 yield() // yield to both waiters
104 finish(13)
Roman Elizarovdaa79222017-01-26 11:31:31 +0300105 }
Roman Elizarovb6b01252017-02-06 13:17:40 +0300106
107 class BadClass {
108 override fun equals(other: Any?): Boolean = error("equals")
109 override fun hashCode(): Int = error("hashCode")
110 override fun toString(): String = error("toString")
111 }
112
113 @Test
114 fun testDeferBadClass() = runBlocking {
115 val bad = BadClass()
Roman Elizarov32d95322017-02-09 15:57:31 +0300116 val d = async(context) {
Roman Elizarovb6b01252017-02-06 13:17:40 +0300117 expect(1)
118 bad
119 }
120 assertTrue(d.await() === bad)
121 finish(2)
122 }
Roman Elizarov41c5c8b2017-01-25 13:37:15 +0300123}