blob: 2eac23cc3656f4c765fe0c6c4c314a322e73a4f2 [file] [log] [blame]
Roman Elizarove3f28842017-12-21 19:15:40 +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
17@file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913
18
19package kotlinx.coroutines.experimental
20
Roman Elizarov9fe5f462018-02-21 19:05:52 +030021import kotlin.coroutines.experimental.*
Roman Elizarove3f28842017-12-21 19:15:40 +030022import kotlin.test.*
23
Roman Elizarovaa461cf2018-04-11 13:20:29 +030024class AsyncTest : TestBase() {
Roman Elizarove3f28842017-12-21 19:15:40 +030025 @Test
26 fun testSimple() = runTest {
27 expect(1)
28 val d = async(coroutineContext) {
29 expect(3)
30 42
31 }
32 expect(2)
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030033 assertTrue(d.isActive)
34 assertTrue(d.await() == 42)
35 assertTrue(!d.isActive)
Roman Elizarove3f28842017-12-21 19:15:40 +030036 expect(4)
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030037 assertTrue(d.await() == 42) // second await -- same result
Roman Elizarove3f28842017-12-21 19:15:40 +030038 finish(5)
39 }
40
41 @Test
42 fun testUndispatched() = runTest {
43 expect(1)
44 val d = async(coroutineContext, start = CoroutineStart.UNDISPATCHED) {
45 expect(2)
46 42
47 }
48 expect(3)
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030049 assertTrue(!d.isActive)
50 assertTrue(d.await() == 42)
Roman Elizarove3f28842017-12-21 19:15:40 +030051 finish(4)
52 }
53
54 @Test
55 fun testSimpleException() = runTest(
56 expected = { it is TestException }
57 ) {
58 expect(1)
59 val d = async(coroutineContext) {
60 finish(3)
61 throw TestException()
62 }
63 expect(2)
64 d.await() // will throw IOException
65 }
66
67 @Test
68 fun testDeferAndYieldException() = runTest(
69 expected = { it is TestException }
70 ) {
71 expect(1)
72 val d = async(coroutineContext) {
73 expect(3)
74 yield() // no effect, parent waiting
75 finish(4)
76 throw TestException()
77 }
78 expect(2)
79 d.await() // will throw IOException
80 }
81
82 @Test
83 fun testDeferWithTwoWaiters() = runTest {
84 expect(1)
85 val d = async(coroutineContext) {
86 expect(5)
87 yield()
88 expect(9)
89 42
90 }
91 expect(2)
92 launch(coroutineContext) {
93 expect(6)
Roman Elizarovc0d71dc2017-12-21 22:12:43 +030094 assertTrue(d.await() == 42)
Roman Elizarove3f28842017-12-21 19:15:40 +030095 expect(11)
96 }
97 expect(3)
98 launch(coroutineContext) {
99 expect(7)
Roman Elizarovc0d71dc2017-12-21 22:12:43 +0300100 assertTrue(d.await() == 42)
Roman Elizarove3f28842017-12-21 19:15:40 +0300101 expect(12)
102 }
103 expect(4)
104 yield() // this actually yields control to async, which produces results and resumes both waiters (in order)
105 expect(8)
106 yield() // yield again to "d", which completes
107 expect(10)
108 yield() // yield to both waiters
109 finish(13)
110 }
111
112 class BadClass {
113 override fun equals(other: Any?): Boolean = error("equals")
114 override fun hashCode(): Int = error("hashCode")
115 override fun toString(): String = error("toString")
116 }
117
118 @Test
119 fun testDeferBadClass() = runTest {
120 val bad = BadClass()
121 val d = async(coroutineContext) {
122 expect(1)
123 bad
124 }
125 assertTrue(d.await() === bad)
126 finish(2)
127 }
128
129 private class TestException : Exception()
130}