Skip to content

Instantly share code, notes, and snippets.

@solidogen
Created August 25, 2019 08:57
Show Gist options
  • Save solidogen/71ce57da995d113b2da0b6a2d69e1768 to your computer and use it in GitHub Desktop.
Save solidogen/71ce57da995d113b2da0b6a2d69e1768 to your computer and use it in GitHub Desktop.
package com.spyrdonapps.currencyconverter.test.util
/*
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import com.google.common.truth.Truth
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.withTimeout
/**
* Represents a list of capture values from a LiveData.
*
* This class is not threadsafe and must be used from the main thread.
*/
class LiveDataValueCapture<T> {
private val _values = mutableListOf<T?>()
val values: List<T?>
get() = _values
val channel = Channel<T?>(Channel.UNLIMITED)
fun addValue(value: T?) {
_values += value
channel.offer(value)
}
suspend fun assertSendsValues(timeout: Long, vararg expected: T?) {
val expectedList = expected.asList()
if (values == expectedList) {
return
}
try {
withTimeout(timeout) {
for (value in channel) {
if (values == expectedList) {
return@withTimeout
}
}
}
} catch (ex: TimeoutCancellationException) {
Truth.assertThat(values).isEqualTo(expectedList)
}
}
}
/**
* Extension function to capture all values that are emitted to a LiveData<T> during the execution of
* `captureBlock`.
*
* @param captureBlock a lambda that will
*/
inline fun <T> LiveData<T>.captureValues(block: LiveDataValueCapture<T>.() -> Unit) {
val capture = LiveDataValueCapture<T>()
val observer = Observer<T> {
capture.addValue(it)
}
observeForever(observer)
capture.block()
removeObserver(observer)
}
/**
* Get the current value from a LiveData without needing to register an observer.
*/
fun <T> LiveData<T>.getValueForTest(): T? {
var value: T? = null
var observer = Observer<T> {
value = it
}
observeForever(observer)
removeObserver(observer)
return value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment