Coverage Summary for Class: ClientConnection (kweb.client)

Class Method, % Branch, % Line, % Instruction, %
ClientConnection 100% (1/1) 100% (1/1) 100% (2/2)
ClientConnection$Caching 100% (4/4) 50% (4/8) 100% (12/12) 76.7% (56/73)
ClientConnection$WebSocket 66.7% (2/3) 87.5% (7/8) 91.1% (51/56)
ClientConnection$WebSocket$1 100% (1/1) 50% (1/2) 100% (3/3) 100% (48/48)
ClientConnection$WebSocket$send$1 100% (1/1) 100% (2/2) 100% (22/22)
Total 90% (9/10) 50% (5/10) 96.2% (25/26) 89.1% (179/201)


 package kweb.client
 
 import io.ktor.websocket.Frame
 import io.ktor.websocket.Frame.Text
 import io.ktor.websocket.WebSocketSession
 import kotlinx.coroutines.*
 import kotlinx.coroutines.channels.Channel
 import mu.KotlinLogging
 import java.util.concurrent.ConcurrentLinkedQueue
 
 private val logger = KotlinLogging.logger {}
 
 sealed class ClientConnection {
 
     abstract fun send(message: String)
 
     //@ObsoleteCoroutinesApi // TODO: For Channel.consumeEach, which will apparently become obsolete
     class WebSocket(private val channel: WebSocketSession) : ClientConnection() {
 
         @Volatile
         var sendCount = 0
 
         private val sendBuffer = Channel<Frame>(capacity = 1000)
 
         init {
             channel.launch {
                 for (frame in sendBuffer) {
                     channel.send(frame)
                 }
             }
         }
 
         override fun send(message: String) {
             runBlocking {
                 sendBuffer.send(Text(message))
             }
             sendCount++
         }
     }
 
     class Caching : ClientConnection() {
         private @Volatile
         var queue: ConcurrentLinkedQueue<String>? = ConcurrentLinkedQueue()
 
         override fun send(message: String) {
             logger.debug("Caching '$message' as websocket isn't yet available")
             queue.let {
                 it?.add(message) ?: error("Can't write to queue after it has been read")
             }
         }
 
         val size = queue?.size ?: 0
 
         fun read(): List<String> {
             queue.let {
                 if (it == null) error("Queue can only be read once")
                 else {
                     val r = it.toList()
                     queue = null
                     return r
                 }
             }
         }
 
         fun queueSize() = queue?.size
     }
 
 }