Roman Elizarov | 3aed4ee | 2017-03-06 12:21:05 +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 | 3aed4ee | 2017-03-06 12:21:05 +0300 | [diff] [blame] | 3 | */ |
| 4 | |
| 5 | package kotlinx.coroutines.experimental.channels |
| 6 | |
Roman Elizarov | 9fe5f46 | 2018-02-21 19:05:52 +0300 | [diff] [blame] | 7 | import kotlinx.coroutines.experimental.* |
Roman Elizarov | 9fe5f46 | 2018-02-21 19:05:52 +0300 | [diff] [blame] | 8 | import kotlin.coroutines.experimental.* |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 9 | import kotlin.test.* |
Roman Elizarov | 3aed4ee | 2017-03-06 12:21:05 +0300 | [diff] [blame] | 10 | |
| 11 | class ConflatedChannelTest : TestBase() { |
| 12 | @Test |
| 13 | fun testBasicConflationOfferPoll() { |
| 14 | val q = ConflatedChannel<Int>() |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 15 | assertNull(q.poll()) |
| 16 | assertTrue(q.offer(1)) |
| 17 | assertTrue(q.offer(2)) |
| 18 | assertTrue(q.offer(3)) |
| 19 | assertEquals(3, q.poll()) |
| 20 | assertNull(q.poll()) |
Roman Elizarov | 3aed4ee | 2017-03-06 12:21:05 +0300 | [diff] [blame] | 21 | } |
| 22 | |
| 23 | @Test |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 24 | fun testConflatedSend() = runTest { |
Roman Elizarov | e6e8ce8 | 2017-06-05 17:04:39 +0300 | [diff] [blame] | 25 | val q = ConflatedChannel<Int>() |
| 26 | q.send(1) |
| 27 | q.send(2) // shall conflated previously sent |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 28 | assertEquals(2, q.receiveOrNull()) |
Roman Elizarov | e6e8ce8 | 2017-06-05 17:04:39 +0300 | [diff] [blame] | 29 | } |
| 30 | |
| 31 | @Test |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 32 | fun testConflatedClose() = runTest { |
Roman Elizarov | e6e8ce8 | 2017-06-05 17:04:39 +0300 | [diff] [blame] | 33 | val q = ConflatedChannel<Int>() |
| 34 | q.send(1) |
| 35 | q.close() // shall conflate sent item and become closed |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 36 | assertNull(q.receiveOrNull()) |
Roman Elizarov | e6e8ce8 | 2017-06-05 17:04:39 +0300 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | @Test |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 40 | fun testConflationSendReceive() = runTest { |
Roman Elizarov | 3aed4ee | 2017-03-06 12:21:05 +0300 | [diff] [blame] | 41 | val q = ConflatedChannel<Int>() |
| 42 | expect(1) |
Roman Elizarov | 43e3af7 | 2017-07-21 16:01:31 +0300 | [diff] [blame] | 43 | launch(coroutineContext) { // receiver coroutine |
Roman Elizarov | 3aed4ee | 2017-03-06 12:21:05 +0300 | [diff] [blame] | 44 | expect(4) |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 45 | assertEquals(2, q.receive()) |
Roman Elizarov | 3aed4ee | 2017-03-06 12:21:05 +0300 | [diff] [blame] | 46 | expect(5) |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 47 | assertEquals(3, q.receive()) // this receive suspends |
Roman Elizarov | 3aed4ee | 2017-03-06 12:21:05 +0300 | [diff] [blame] | 48 | expect(8) |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 49 | assertEquals(6, q.receive()) // last conflated value |
Roman Elizarov | 3aed4ee | 2017-03-06 12:21:05 +0300 | [diff] [blame] | 50 | expect(9) |
| 51 | } |
| 52 | expect(2) |
| 53 | q.send(1) |
| 54 | q.send(2) // shall conflate |
| 55 | expect(3) |
| 56 | yield() // to receiver |
| 57 | expect(6) |
| 58 | q.send(3) // send to the waiting receiver |
| 59 | q.send(4) // buffer |
| 60 | q.send(5) // conflate |
| 61 | q.send(6) // conflate again |
| 62 | expect(7) |
| 63 | yield() // to receiver |
| 64 | finish(10) |
| 65 | } |
Roman Elizarov | b555d91 | 2017-08-17 21:01:33 +0300 | [diff] [blame] | 66 | |
| 67 | @Test |
Vsevolod Tolstopyatov | 9619134 | 2018-04-20 18:13:33 +0300 | [diff] [blame] | 68 | fun testConsumeAll() = runTest { |
Roman Elizarov | b555d91 | 2017-08-17 21:01:33 +0300 | [diff] [blame] | 69 | val q = ConflatedChannel<Int>() |
| 70 | expect(1) |
| 71 | for (i in 1..10) { |
| 72 | q.send(i) // stores as last |
| 73 | } |
| 74 | q.cancel() |
| 75 | check(q.isClosedForSend) |
| 76 | check(q.isClosedForReceive) |
| 77 | check(q.receiveOrNull() == null) |
| 78 | finish(2) |
| 79 | } |
Vsevolod Tolstopyatov | 4b9a559 | 2018-04-11 13:17:14 +0300 | [diff] [blame] | 80 | |
Roman Elizarov | f2bdf60 | 2018-04-26 11:29:47 +0300 | [diff] [blame] | 81 | @Test |
| 82 | fun testCancelWithCause() = runTest({ it is TestException }) { |
Vsevolod Tolstopyatov | 4b9a559 | 2018-04-11 13:17:14 +0300 | [diff] [blame] | 83 | val channel = ConflatedChannel<Int>() |
Roman Elizarov | f2bdf60 | 2018-04-26 11:29:47 +0300 | [diff] [blame] | 84 | channel.cancel(TestException()) |
Vsevolod Tolstopyatov | 4b9a559 | 2018-04-11 13:17:14 +0300 | [diff] [blame] | 85 | channel.receiveOrNull() |
| 86 | } |
Roman Elizarov | f2bdf60 | 2018-04-26 11:29:47 +0300 | [diff] [blame] | 87 | |
| 88 | private class TestException : Exception() |
Vsevolod Tolstopyatov | 4b9a559 | 2018-04-11 13:17:14 +0300 | [diff] [blame] | 89 | } |