Roman Elizarov | fadf8c8 | 2017-03-02 23:36:06 +0300 | [diff] [blame] | 1 | /* |
Roman Elizarov | 1f74a2d | 2018-06-29 19:19:45 +0300 | [diff] [blame^] | 2 | * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. |
Roman Elizarov | fadf8c8 | 2017-03-02 23:36:06 +0300 | [diff] [blame] | 3 | */ |
4 | |||||
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 5 | @file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913 |
6 | |||||
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 7 | package kotlinx.coroutines.experimental.selects |
8 | |||||
9 | import kotlinx.coroutines.experimental.* | ||||
Roman Elizarov | 9fe5f46 | 2018-02-21 19:05:52 +0300 | [diff] [blame] | 10 | import kotlin.coroutines.experimental.* |
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 11 | import kotlin.test.* |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 12 | |
13 | class SelectDeferredTest : TestBase() { | ||||
14 | @Test | ||||
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 15 | fun testSimpleReturnsImmediately() = runTest { |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 16 | expect(1) |
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 17 | val d1 = async(coroutineContext) { |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 18 | expect(3) |
19 | 42 | ||||
20 | } | ||||
21 | expect(2) | ||||
22 | val res = select<String> { | ||||
23 | d1.onAwait { v -> | ||||
24 | expect(4) | ||||
25 | assertEquals(42, v) | ||||
26 | "OK" | ||||
27 | } | ||||
28 | } | ||||
29 | expect(5) | ||||
30 | assertEquals("OK", res) | ||||
31 | finish(6) | ||||
32 | } | ||||
33 | |||||
34 | @Test | ||||
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 35 | fun testSimpleWithYield() = runTest { |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 36 | expect(1) |
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 37 | val d1 = async(coroutineContext) { |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 38 | expect(3) |
39 | 42 | ||||
40 | } | ||||
Roman Elizarov | 43e3af7 | 2017-07-21 16:01:31 +0300 | [diff] [blame] | 41 | launch(coroutineContext) { |
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 42 | expect(4) |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 43 | yield() // back to main |
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 44 | expect(6) |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 45 | } |
46 | expect(2) | ||||
47 | val res = select<String> { | ||||
48 | d1.onAwait { v -> | ||||
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 49 | expect(5) |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 50 | assertEquals(42, v) |
51 | yield() // to launch | ||||
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 52 | expect(7) |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 53 | "OK" |
54 | } | ||||
55 | } | ||||
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 56 | finish(8) |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 57 | assertEquals("OK", res) |
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 58 | } |
59 | |||||
60 | @Test | ||||
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 61 | fun testSelectIncompleteLazy() = runTest { |
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 62 | expect(1) |
Roman Elizarov | 43e3af7 | 2017-07-21 16:01:31 +0300 | [diff] [blame] | 63 | val d1 = async(coroutineContext, CoroutineStart.LAZY) { |
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 64 | expect(5) |
65 | 42 | ||||
66 | } | ||||
Roman Elizarov | 43e3af7 | 2017-07-21 16:01:31 +0300 | [diff] [blame] | 67 | launch(coroutineContext) { |
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 68 | expect(3) |
69 | val res = select<String> { | ||||
70 | d1.onAwait { v -> | ||||
71 | expect(7) | ||||
72 | assertEquals(42, v) | ||||
73 | "OK" | ||||
74 | } | ||||
75 | } | ||||
76 | expect(8) | ||||
77 | assertEquals("OK", res) | ||||
78 | } | ||||
79 | expect(2) | ||||
80 | yield() // to launch | ||||
81 | expect(4) | ||||
82 | yield() // to started async | ||||
83 | expect(6) | ||||
84 | yield() // to triggered select | ||||
85 | finish(9) | ||||
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 86 | } |
87 | |||||
88 | @Test | ||||
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 89 | fun testSelectTwo() = runTest { |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 90 | expect(1) |
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 91 | val d1 = async(coroutineContext) { |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 92 | expect(3) |
93 | yield() // to the other deffered | ||||
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 94 | expect(5) |
95 | yield() // to fired select | ||||
96 | expect(7) | ||||
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 97 | "d1" |
98 | } | ||||
Roman Elizarov | aa461cf | 2018-04-11 13:20:29 +0300 | [diff] [blame] | 99 | val d2 = async(coroutineContext) { |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 100 | expect(4) |
101 | "d2" // returns result | ||||
102 | } | ||||
103 | expect(2) | ||||
104 | val res = select<String> { | ||||
Roman Elizarov | 7adb876 | 2017-03-17 17:54:13 +0300 | [diff] [blame] | 105 | d1.onAwait { |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 106 | expectUnreached() |
107 | "FAIL" | ||||
108 | } | ||||
109 | d2.onAwait { v2 -> | ||||
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 110 | expect(6) |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 111 | assertEquals("d2", v2) |
112 | yield() // to first deferred | ||||
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 113 | expect(8) |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 114 | "OK" |
115 | } | ||||
116 | } | ||||
117 | assertEquals("OK", res) | ||||
Roman Elizarov | d84dbc2 | 2017-02-22 14:56:58 +0300 | [diff] [blame] | 118 | finish(9) |
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 119 | } |
120 | |||||
Roman Elizarov | 8b38fa2 | 2017-09-27 17:44:31 +0300 | [diff] [blame] | 121 | @Test |
122 | fun testSelectCancel() = runTest( | ||||
123 | expected = { it is JobCancellationException } | ||||
124 | ) { | ||||
125 | expect(1) | ||||
126 | val d = CompletableDeferred<String>() | ||||
127 | launch (coroutineContext) { | ||||
128 | finish(3) | ||||
129 | d.cancel() // will cancel after select starts | ||||
130 | } | ||||
131 | expect(2) | ||||
132 | select<Unit> { | ||||
133 | d.onAwait { | ||||
134 | expectUnreached() // will not select | ||||
135 | } | ||||
136 | } | ||||
137 | expectUnreached() | ||||
138 | } | ||||
139 | |||||
Roman Elizarov | 1216e91 | 2017-02-22 09:57:06 +0300 | [diff] [blame] | 140 | } |