diff --git a/kotlinx-coroutines-core/common/test/channels/BasicOperationsTest.kt b/kotlinx-coroutines-core/common/test/channels/BasicOperationsTest.kt index fb9e0d9cf1..03c5f7457f 100644 --- a/kotlinx-coroutines-core/common/test/channels/BasicOperationsTest.kt +++ b/kotlinx-coroutines-core/common/test/channels/BasicOperationsTest.kt @@ -8,31 +8,31 @@ class BasicOperationsTest : TestBase() { @Test fun testSimpleSendReceive() = runTest { // Parametrized common test :( - TestChannelKind.values().forEach { kind -> testSendReceive(kind, 20) } + TestChannelKind.entries.forEach { kind -> testSendReceive(kind, 20) } } @Test fun testTrySendToFullChannel() = runTest { - TestChannelKind.values().forEach { kind -> testTrySendToFullChannel(kind) } + TestChannelKind.entries.forEach { kind -> testTrySendToFullChannel(kind) } } @Test fun testTrySendAfterClose() = runTest { - TestChannelKind.values().forEach { kind -> testTrySendAfterClose(kind) } + TestChannelKind.entries.forEach { kind -> testTrySendAfterClose(kind) } } @Test fun testSendAfterClose() = runTest { - TestChannelKind.values().forEach { kind -> testSendAfterClose(kind) } + TestChannelKind.entries.forEach { kind -> testSendAfterClose(kind) } } @Test fun testReceiveCatching() = runTest { - TestChannelKind.values().forEach { kind -> testReceiveCatching(kind) } + TestChannelKind.entries.forEach { kind -> testReceiveCatching(kind) } } @Test - fun testInvokeOnClose() = TestChannelKind.values().forEach { kind -> + fun testInvokeOnClose() = TestChannelKind.entries.forEach { kind -> reset() val channel = kind.create() channel.invokeOnClose { @@ -48,7 +48,7 @@ class BasicOperationsTest : TestBase() { } @Test - fun testInvokeOnClosed() = TestChannelKind.values().forEach { kind -> + fun testInvokeOnClosed() = TestChannelKind.entries.forEach { kind -> reset() expect(1) val channel = kind.create() @@ -59,7 +59,7 @@ class BasicOperationsTest : TestBase() { } @Test - fun testMultipleInvokeOnClose() = TestChannelKind.values().forEach { kind -> + fun testMultipleInvokeOnClose() = TestChannelKind.entries.forEach { kind -> reset() val channel = kind.create() channel.invokeOnClose { expect(3) } @@ -71,14 +71,16 @@ class BasicOperationsTest : TestBase() { } @Test - fun testIterator() = runTest { - TestChannelKind.values().forEach { kind -> + fun testIteratorHasNextMustPrecedeNext() = runTest { + TestChannelKind.entries.forEach { kind -> val channel = kind.create() val iterator = channel.iterator() assertFailsWith { iterator.next() } channel.close() assertFailsWith { iterator.next() } assertFalse(iterator.hasNext()) + assertFailsWith { iterator.next() } + assertFailsWith { iterator.next() } } } @@ -109,7 +111,7 @@ class BasicOperationsTest : TestBase() { try { expect(2) channel.close() - } catch (e: TestException) { + } catch (_: TestException) { expect(4) } } diff --git a/kotlinx-coroutines-core/common/test/channels/ClosedChannelTest.kt b/kotlinx-coroutines-core/common/test/channels/ClosedChannelTest.kt new file mode 100644 index 0000000000..3731d11575 --- /dev/null +++ b/kotlinx-coroutines-core/common/test/channels/ClosedChannelTest.kt @@ -0,0 +1,123 @@ +package kotlinx.coroutines.channels + +import kotlinx.coroutines.testing.* +import kotlin.test.* + +class ClosedChannelTest : TestBase() { + /** + * Iterator. + */ + + @Test + fun testIteratorClosedHasNextFalse() = runTest { + TestChannelKind.entries.forEach { kind -> + val channel = kind.create() + val iterator = channel.iterator() + channel.close() + assertFalse(iterator.hasNext()) + } + } + + @Test + fun testIteratorClosedWithExceptionHasNextThrows() = runTest { + TestChannelKind.entries.forEach { kind -> + val channel = kind.create() + val iterator = channel.iterator() + channel.close(TestException()) + assertFailsWith { (iterator.hasNext()) } + } + } + + @Test + fun testClosedToListOk() = runTest { + TestChannelKind.entries.forEach { kind -> + val channel = kind.create() + channel.close() + channel.toList() + } + } + + /** + * Properties. + * + * Properties stay the same regardless of whether the channel was closed with or without exception. + */ + + @Test + fun testClosedIsClosedForReceive() = runTest { + TestChannelKind.entries.forEach { kind -> + val channel = kind.create() + assertFalse(channel.isClosedForReceive) + channel.close() + assertTrue(channel.isClosedForReceive) + } + } + + @Test + fun testClosedWithExceptionIsClosedForReceive() = runTest { + TestChannelKind.entries.forEach { kind -> + val channel = kind.create() + assertFalse(channel.isClosedForReceive) + channel.close(TestException()) + assertTrue(channel.isClosedForReceive) + } + } + + @Test + fun testClosedIsEmptyFalse() = runTest { + TestChannelKind.entries.forEach { kind -> + val channel = kind.create() + assertTrue(channel.isEmpty) + assertFalse(channel.isClosedForReceive) + channel.close() + // NB! Not obvious. + assertFalse(channel.isEmpty) + assertTrue(channel.isClosedForReceive) + } + } + + @Test + fun testClosedWithExceptionIsEmptyFalse() = runTest { + TestChannelKind.entries.forEach { kind -> + val channel = kind.create() + assertTrue(channel.isEmpty) + assertFalse(channel.isClosedForReceive) + channel.close(TestException()) + assertFalse(channel.isEmpty) + assertTrue(channel.isClosedForReceive) + } + } + + @Test + fun testSendClosedReceiveIsEmptyFalse() = runTest { + val channel = Channel(1) + assertTrue(channel.isEmpty) + assertFalse(channel.isClosedForReceive) + channel.send(1) + assertFalse(channel.isEmpty) + assertFalse(channel.isClosedForReceive) + channel.close() + assertFalse(channel.isEmpty) + assertFalse(channel.isClosedForReceive) + channel.receive() + assertFalse(channel.isEmpty) + assertTrue(channel.isClosedForReceive) + } + + @Test + fun testSendClosedWithExceptionReceiveIsEmptyFalse() = runTest { + val channel = Channel(1) + assertTrue(channel.isEmpty) + assertFalse(channel.isClosedForReceive) + channel.send(1) + assertFalse(channel.isEmpty) + assertFalse(channel.isClosedForReceive) + channel.close(TestException()) + assertFalse(channel.isEmpty) + assertFalse(channel.isClosedForReceive) + channel.receive() + assertFalse(channel.isEmpty) + assertTrue(channel.isClosedForReceive) + } + +}