Exercise: ApplicationScope
You need to create an ApplicationScope class that implements the CoroutineScope, ApplicationControlScope and LoggingScope interfaces. It should expect primary constructor properties of the same types and use them as delegates. Use interface delegation to implement this.
interface ApplicationControlScope {
val application: Application
fun start()
fun stop()
fun isRunning(): Boolean
}
data class Application(val name: String)
interface LoggingScope {
fun logInfo(message: String)
fun logWarning(message: String)
fun logError(message: String)
}
This problem can either be solved in the below playground or you can clone
kotlin-exercises project and solve it locally. In the project, you can find code template for this exercise in advanced/delegates/ApplicationScope.kt. You can find there unit tests.
Once you are done with the exercise, you can check your solution
here.
Playground
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.SupervisorJob
import org.junit.Test
import kotlin.coroutines.EmptyCoroutineContext
// TODO
interface ApplicationControlScope {
val application: Application
fun start()
fun stop()
fun isRunning(): Boolean
}
data class Application(val name: String)
interface LoggingScope {
fun logInfo(message: String)
fun logWarning(message: String)
fun logError(message: String)
}
class ApplicationScopeTest {
private val fakeApplicationScope = FakeApplicationControlScope(
application = Application("Test"),
)
private val fakeLoggingScope = FakeLoggingScope()
private val coroutineScope = CoroutineScope(SupervisorJob())
private val applicationScope = ApplicationScope(
scope = coroutineScope,
applicationScope = fakeApplicationScope,
loggingScope = fakeLoggingScope,
)
@Test
fun `should use coroutine scope`() {
assert(applicationScope.coroutineContext == coroutineScope.coroutineContext)
}
@Test
fun `should use application scope`() {
assert(applicationScope.application.name == "Test")
applicationScope.start()
assert(fakeApplicationScope.isRunning())
applicationScope.stop()
assert(!fakeApplicationScope.isRunning())
}
@Test
fun `should use logging scope`() {
applicationScope.logInfo("Info")
applicationScope.logWarning("Warning")
applicationScope.logError("Error")
assert(fakeLoggingScope.messages == listOf(
"INFO: Info",
"WARNING: Warning",
"ERROR: Error",
))
}
}
class FakeApplicationControlScope(
override val application: Application,
) : ApplicationControlScope {
private var started = false
override fun start() {
started = true
}
override fun stop() {
started = false
}
override fun isRunning(): Boolean = started
}
class FakeLoggingScope : LoggingScope {
val messages = mutableListOf<String>()
override fun logInfo(message: String) {
messages += "INFO: $message"
}
override fun logWarning(message: String) {
messages += "WARNING: $message"
}
override fun logError(message: String) {
messages += "ERROR: $message"
}
}