| /* |
| * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. |
| * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. |
| */ |
| |
| package test.autoCloseable |
| |
| import kotlin.test.* |
| |
| class UseAutoCloseableResourceTest { |
| |
| class Resource(val faultyClose: Boolean = false) : AutoCloseable { |
| |
| var isClosed = false |
| private set |
| |
| override fun close() { |
| if (faultyClose) |
| throw ResourceCloseException("Close failed") |
| isClosed = true |
| } |
| } |
| |
| class ResourceCloseException(message: String) : Exception(message) |
| |
| |
| @Test fun success() { |
| val resource = Resource() |
| val result = resource.use { "ok" } |
| assertEquals("ok", result) |
| assertTrue(resource.isClosed) |
| } |
| |
| @Test fun closeFails() { |
| val e = assertFails { |
| Resource(faultyClose = true).use { it.isClosed } |
| } |
| assertTrue(e is ResourceCloseException) |
| } |
| |
| @Test fun opFailsCloseSuccess() { |
| val e = assertFails { |
| Resource().use { error("op fail") } |
| } |
| assertTrue(e is IllegalStateException) |
| assertTrue(e.suppressedExceptions.isEmpty()) |
| } |
| |
| @Test fun opFailsCloseFails() { |
| val e = assertFails { |
| Resource(faultyClose = true).use { error("op fail") } |
| } |
| assertTrue(e is IllegalStateException) |
| assertTrue(e.suppressedExceptions.single() is ResourceCloseException) |
| } |
| |
| @Test fun opFailsCloseFailsTwice() { |
| val e = assertFails { |
| Resource(faultyClose = true).use { _ -> |
| Resource(faultyClose = true).use { _ -> |
| error("op fail") |
| } |
| } |
| } |
| assertTrue(e is IllegalStateException) |
| val suppressed = e.suppressedExceptions |
| assertEquals(2, suppressed.size) |
| assertTrue(suppressed.all { it is ResourceCloseException }) |
| } |
| |
| @Test fun nonLocalReturnInBlock() { |
| fun Resource.operation(nonLocal: Boolean): String { |
| return use { if (nonLocal) return "nonLocal" else "local" } |
| } |
| |
| Resource().let { resource -> |
| val result = resource.operation(nonLocal = false) |
| assertEquals("local", result) |
| assertTrue(resource.isClosed) |
| } |
| |
| Resource().let { resource -> |
| val result = resource.operation(nonLocal = true) |
| assertEquals("nonLocal", result) |
| assertTrue(resource.isClosed) |
| } |
| } |
| |
| |
| @Test fun nullableResourceSuccess() { |
| val resource: Resource? = null |
| val result = resource.use { "ok" } |
| assertEquals("ok", result) |
| } |
| |
| @Test fun nullableResourceOpFails() { |
| val resource: Resource? = null |
| val e = assertFails { |
| resource.use { requireNotNull(it) } |
| } |
| assertTrue(e is IllegalArgumentException) |
| assertTrue(e.suppressedExceptions.isEmpty()) |
| } |
| |
| @Test |
| fun contractCallsInPlace() { |
| val i: Int |
| Resource().use { _ -> |
| Resource().use { _ -> |
| i = 1 |
| } |
| } |
| assertEquals(1, i) |
| } |
| } |