val authRecord = try { AuthenticationRecord( apiKey = localUser.apiKey!!, username = localUser.username!!, userId = localUser.userId!! ) } catch (exception: KotlinNullPointerException) { // Provide an error to the user because they // aren't authenticated. }
aren't authenticated. } val authRecord = if ( localUser.apiKey != null && localUser.username != null && localUser.userId != null) { AuthenticationRecord( localUser.apiKey, localUser.username, localUser.userId ) } else { // Provide an error to the user because they // aren't authenticated. }
because they // aren't authenticated. } val authRecord = try { AuthenticationRecord( apiKey = localUser.apiKey!!, username = localUser.username!!, userId = localUser.userId!! ) } catch (exception: KotlinNullPointerException) { // Provide an error to the user because they // aren't authenticated. }
val age: Int = 4 ) val tina = Cat() tina.name // Tina tina.age // 4 tina.equals(Cat(name = "Tina")) // true tina.hashCode() // some number val (name, age) = tina val tinaIsOlder = tina.copy(age = 5) // older Sometimes classes exist for the sole purpose of containing data. This is where data classes shine. engel.dev
= 4 ) val tina = Cat() tina.name // Tina tina.age // 4 tina.equals(Cat(name = "Tina")) // true tina.hashCode() // some number val (name, age) = tina val tinaIsOlder = tina.copy(age = 5) // older Normal Boring Class.
= 4 ) val tina = Cat() tina.name // Tina tina.age // 4 tina.equals(Cat(name = "Tina")) // false tina.hashCode() // some number val (name, age) = tina val tinaIsOlder = tina.copy(age = 5) // older Normal Boring Class.
= 4 ) val tina = Cat() tina.name // Tina tina.age // 4 tina.equals(Cat(name = "Tina")) // false tina.hashCode() // some number, but calculated differently val (name, age) = tina val tinaIsOlder = tina.copy(age = 5) // older Normal Boring Class.
= 4 ) val tina = Cat() tina.name // Tina tina.age // 4 tina.equals(Cat(name = "Tina")) // false tina.hashCode() // some number, but calculated differently val (name, age) = tina val tinaIsOlder = tina.copy(age = 5) // older Normal Boring Class.
= 4 ) val tina = Cat() tina.name // Tina tina.age // 4 tina.equals(Cat(name = "Tina")) // false tina.hashCode() // some number, but calculated differently val (name, age) = tina val tinaIsOlder = tina.copy(age = 5) Normal Boring Class.
Int = 4 ) val tinaIsOlder = tina.copy(age = 5) val shouldBeTrue = tina.equals(Cat(name = “Tina")) val shouldBeConsistent = tina.hashCode() Using Data Classes.
String?, val title: String?, val order: Long?, val type: String?, val fieldValueId: Long? ) { data class StandardFieldValue( private val _fieldId: Long?, private val _value: String?, private val _title: String?, private val _order: Long?, private val _type: String?, private val _fieldValueId: Long? ) : DealCustomFieldValue( _fieldId, _value, _title, _order, _type, _fieldValueId ) data class NumberFieldValue( private val _fieldId: Long?, private val _value: String?, private val _title: String?, private val _order: Long?, private val _type: String?, private val _fieldValueId: Long? ) : DealCustomFieldValue( _fieldId, _value, _title, _order, _type, _fieldValueId ) data class CurrencyFieldValue( private val _fieldId: Long?, private val _value: String?, private val _title: String?, private val _order: Long?, private val _type: String?, private val _fieldValueId: Long?, val fieldCurrency: String?, val currencyPosition: String? ) : DealCustomFieldValue( _fieldId, _value, _title, _order, _type, _fieldValueId ) } Used for representing restricted class hierarchies. They are like an extension on enum classes where sub- classes can have multiple instances available at a time. engel.dev
val _value: String?, private val _title: String?, private val _order: Long?, private val _type: String?, private val _fieldValueId: Long? ) : DealCustomFieldValue( _fieldId,
String?, private val _title: String?, private val _order: Long?, private val _type: String?, private val _fieldValueId: Long?, val fieldCurrency: String?, val currencyPosition: String? ) : DealCustomFieldValue(
value: String? abstract val title: String? abstract val order: Long? abstract val type: String? abstract val fieldValueId: Long? data class StandardFieldValue( override val fieldId: Long?,
String?, override val title: String?, override val order: Long?, override val type: String?, override val fieldValueId: Long? ) : DealCustomFieldValue() data class NumberFieldValue( override val fieldId: Long?,
String?, override val title: String?, override val order: Long?, override val type: String?, override val fieldValueId: Long?, val fieldCurrency: String?, val currencyPosition: String? ) : DealCustomFieldValue()
title: String?, val order: Long?, val type: String?, val fieldValueId: Long? ) { data class StandardFieldValue( private val _fieldId: Long?, private val _value: String?, private val _title: String?, private val _order: Long?, private val _type: String?, private val _fieldValueId: Long? ) : DealCustomFieldValue( _fieldId, _value, _title, _order, _type, _fieldValueId ) data class NumberFieldValue( private val _fieldId: Long?, private val _value: String?, private val _title: String?, private val _order: Long?, private val _type: String?, private val _fieldValueId: Long? ) : DealCustomFieldValue( _fieldId, _value, _title, _order, _type, _fieldValueId ) data class CurrencyFieldValue( private val _fieldId: Long?, private val _value: String?, private val _title: String?, private val _order: Long?, private val _type: String?, private val _fieldValueId: Long?, val fieldCurrency: String?, val currencyPosition: String? ) : DealCustomFieldValue( _fieldId, _value, _title, _order, _type, _fieldValueId ) } sealed class DealCustomFieldValue { abstract val fieldId: Long? abstract val value: String? abstract val title: String? abstract val order: Long? abstract val type: String? abstract val fieldValueId: Long? data class StandardFieldValue( override val fieldId: Long?, override val value: String?, override val title: String?, override val order: Long?, override val type: String?, override val fieldValueId: Long? ) : DealCustomFieldValue() data class NumberFieldValue( override val fieldId: Long?, override val value: String?, override val title: String?, override val order: Long?, override val type: String?, override val fieldValueId: Long? ) : DealCustomFieldValue() data class CurrencyFieldValue( override val fieldId: Long?, override val value: String?, override val title: String?, override val order: Long?, override val type: String?, override val fieldValueId: Long?, val fieldCurrency: String?, val currencyPosition: String? ) : DealCustomFieldValue() }
{ is DealCustomFieldValue.CurrencyFieldValue -> { createStandardField( title = title ?: "", body = currencyUtil.serverValueToDisplayValue( value?.toDouble(), currencyPosition, fieldCurrency ), leftIcon = R.drawable.ic_short_text ) } is DealCustomFieldValue.NumberFieldValue -> createStandardField( title = title ?: "", body = value.toDoubleFormatTwoDecimalPlaces(), leftIcon = R.drawable.ic_short_text ) is DealCustomFieldValue.StandardFieldValue -> createStandardField( title = title ?: “", body = value ?: “", leftIcon = R.drawable.ic_short_text ) } } }
{ createStandardField( title = title ?: "", body = value.toDoubleFormatTwoDecimalPlaces(), leftIcon = R.drawable.ic_short_text ) } is DealCustomFieldValue.StandardFieldValue -> {} }
{ createStandardField( title = title ?: "", body = value.toDoubleFormatTwoDecimalPlaces(), leftIcon = R.drawable.ic_short_text ) } is DealCustomFieldValue.StandardFieldValue -> { createStandardField( title = title ?: “", body = value ?: “", leftIcon = R.drawable.ic_short_text ) } }
List of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Cats grouped by their age. cats.random() // Random Cat from the list. The Collections framework that ships with Kotlin makes working with collections a breeze. engel.dev
of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. Collections.kt Abbreviated.
of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. Collections.kt Abbreviated.
of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. Collections.kt Abbreviated.
of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. Collections.kt Abbreviated.
of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. Collections.kt Abbreviated.
of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. Collections.kt Abbreviated.
of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. Collections.kt Abbreviated.
of Ages. cats.filter { it.age > 4 } // List of Cats older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. Collections.kt Abbreviated.
older than 4. cats.last { it.name == "Tina" } // Last Cat named Tina. cats.slice(5..10) // Cats within the range of 5 to 10. cats.takeLast(15) // The last 15 Cats in the list. cats.groupBy { it.age } // Group Cats by their age. cats.random() // Random Cat from the list. cats .filter { it.age > 4 } .random() // Random Cat, older than 4.
4. cats .filter { it.age > 4 } .takeLast(20) .random() cats .takeLast(20) // New list of 20 cats. .filter { it.age > 4 } // New list containing only cats older than 4. .random()
sealed class FieldValue<T> { abstract val value: T data class NumericField(override val value: Long) : FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() }
: FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() } val fieldValues = listOf<FieldValue>() val fieldGroup = mutableMapOf<KClass, MutableList<FieldValue>>() for (fieldValue in fieldValues) { val fieldGroupValues = fieldGroup[fieldValue::class] ?: mutableListOf() fieldGroupValues.add(fieldValue) fieldGroup[fieldValue::class] = fieldGroupValues }
: FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() } val fieldValues = listOf<FieldValue>() val fieldGroup = mutableMapOf<KClass, MutableList<FieldValue>>() for (fieldValue in fieldValues) { val fieldGroupValues = fieldGroup[fieldValue::class] ?: mutableListOf() fieldGroupValues.add(fieldValue) fieldGroup[fieldValue::class] = fieldGroupValues }
: FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() } val fieldValues = listOf<FieldValue>() val fieldGroup = mutableMapOf<KClass, MutableList<FieldValue>>() for (fieldValue in fieldValues) { val fieldGroupValues = fieldGroup[fieldValue::class] ?: mutableListOf() fieldGroupValues.add(fieldValue) fieldGroup[fieldValue::class] = fieldGroupValues }
: FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() } val fieldValues = listOf<FieldValue>() val fieldGroup = mutableMapOf<KClass, MutableList<FieldValue>>() for (fieldValue in fieldValues) { val fieldGroupValues = fieldGroup[fieldValue::class] ?: mutableListOf() fieldGroupValues.add(fieldValue) fieldGroup[fieldValue::class] = fieldGroupValues }
: FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() } val fieldValues = listOf<FieldValue>() val fieldGroup = mutableMapOf<KClass, MutableList<FieldValue>>() for (fieldValue in fieldValues) { val fieldGroupValues = fieldGroup[fieldValue::class] ?: mutableListOf() fieldGroupValues.add(fieldValue) fieldGroup[fieldValue::class] = fieldGroupValues }
: FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() } val fieldValues = listOf<FieldValue>() val fieldGroup = mutableMapOf<KClass, MutableList<FieldValue>>() for (fieldValue in fieldValues) { val fieldGroupValues = fieldGroup[fieldValue::class] ?: mutableListOf() fieldGroupValues.add(fieldValue) fieldGroup[fieldValue::class] = fieldGroupValues }
: FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() } val fieldValues = listOf<FieldValue>() val fieldGroup = mutableMapOf<KClass, MutableList<FieldValue>>() for (fieldValue in fieldValues) { val fieldGroupValues = fieldGroup[fieldValue::class] ?: mutableListOf() fieldGroupValues.add(fieldValue) fieldGroup[fieldValue::class] = fieldGroupValues }
: FieldValue<Long>() data class MoneyField(override val value: Double) : FieldValue<Double>() data class TextField(override val value: String) : FieldValue<String>() data class MultiSelect<T>(override val value: List<T>) : FieldValue<List<T>>() } val fieldValues = listOf<FieldValue>() val fieldGroup = mutableMapOf<KClass, MutableList<FieldValue>>() for (fieldValue in fieldValues) { val fieldGroupValues = fieldGroup[fieldValue::class] ?: mutableListOf() fieldGroupValues.add(fieldValue) fieldGroup[fieldValue::class] = fieldGroupValues }
Delegate { operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return "$thisRef, thank you for delegating '${property.name}' to me!" } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { println("$value has been assigned to '${property.name}' in $thisRef.") } } class Delegate { operator fun getValue(thisRef: Any?, property: KProperty<*>): String operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) }
When First Needed Then Cached And Reused In The Future """.trimIndent() } operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return "$thisRef, thank you for delegating '${property.name}' to me!" } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { println("$value has been assigned to '${property.name}' in $thisRef.") } }
this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ @file:kotlin.jvm.JvmName("LazyKt") @file:kotlin.jvm.JvmMultifileClass package kotlin /** * Creates a new instance of the [Lazy] that uses the specified initialization function [initializer] * and the default thread-safety mode [LazyThreadSafetyMode.SYNCHRONIZED]. * * If the initialization of a value throws an exception, it will attempt to reinitialize the value at next access. * * Note that the returned instance uses itself to synchronize on. Do not synchronize from external code on
it will attempt to reinitialize the value at next access. * * Note that the returned instance uses itself to synchronize on. Do not synchronize from external code on * the returned instance as it may cause accidental deadlock. Also this behavior can be changed in the future. */ public actual fun <T> lazy(initializer: () -> T): Lazy<T> = SynchronizedLazyImpl(initializer) /** * Creates a new instance of the [Lazy] that uses the specified initialization function [initializer] * and thread-safety [mode]. * * If the initialization of a value throws an exception, it will attempt to reinitialize the value at next access. * * Note that when the [LazyThreadSafetyMode.SYNCHRONIZED] mode is specified the returned instance uses itself * to synchronize on. Do not synchronize from external code on the returned instance as it may cause accidental deadlock.
T): Lazy<T> = SynchronizedLazyImpl(initializer, lock) private class SynchronizedLazyImpl<out T>(initializer: () -> T, lock: Any? = null) : Lazy<T>, Serializable { private var initializer: (() -> T)? = initializer @Volatile private var _value: Any? = UNINITIALIZED_VALUE // final field is required to enable safe publication of constructed instance private val lock = lock ?: this override val value: T get() { val _v1 = _value if (_v1 !== UNINITIALIZED_VALUE) { @Suppress("UNCHECKED_CAST") return _v1 as T } return synchronized(lock) { val _v2 = _value if (_v2 !== UNINITIALIZED_VALUE) {
Long { return { randomNumber() * randomNumber() } } randomerNumber { Random.nextLong() }() Mostly used for passing a function into another function. However you can return a function from a function too. engel.dev
Changed(val positionStart: Int, val itemCount: Int = 1) : DataSetChange() data class Inserted(val positionStart: Int, val itemCount: Int = 1) : DataSetChange() data class Moved(val from: Int, val to: Int) : DataSetChange() data class Removed(val positionStart: Int, val itemCount: Int = 1) : DataSetChange() }
abstract val listViewModel: ListViewModel<T> val dataSetChanges: (change: DataSetChange) -> Unit = { when (it) { is DataSetChange.Inserted -> notifyItemRangeInserted(it.positionStart, it.itemCount) is DataSetChange.Moved -> notifyItemMoved(it.from, it.to) is DataSetChange.Removed -> notifyItemRangeRemoved(it.positionStart, it.itemCount) is DataSetChange.Changed -> notifyItemRangeChanged(it.positionStart, it.itemCount) is DataSetChange.All -> notifyDataSetChanged() } } override fun getItemCount(): Int = listViewModel.itemCount override fun onBindViewHolder(holder: VH, position: Int) { holder.bind(listViewModel[position]) } }
abstract val listViewModel: ListViewModel<T> val dataSetChanges: (change: DataSetChange) -> Unit = { when (it) { is DataSetChange.Inserted -> notifyItemRangeInserted(it.positionStart, it.itemCount) is DataSetChange.Moved -> notifyItemMoved(it.from, it.to) is DataSetChange.Removed -> notifyItemRangeRemoved(it.positionStart, it.itemCount) is DataSetChange.Changed -> notifyItemRangeChanged(it.positionStart, it.itemCount) is DataSetChange.All -> notifyDataSetChanged() } } override fun getItemCount(): Int = listViewModel.itemCount override fun onBindViewHolder(holder: VH, position: Int) { holder.bind(listViewModel[position]) } }
production, then start with your CI/CD process. class LoginViewModelTest : ViewModelTest() { @MockK private lateinit var authenticationRepository: Authenti @MockK private lateinit var stringLoader: StringLoader @MockK private lateinit var telemetry: Telemetry @RelaxedMockK private lateinit var analytics: ActiveCampaignAnalytics private lateinit var subject: LoginViewModel private val viewStateAssertion = ViewStateAssertion<Log private val accountTextChanges by lazy { EventObservabl private val usernameTextChanges by lazy { EventObservab private val passwordTextChanges by lazy { EventObservab private val domainTextChanges by lazy { EventObservable private val loginClicks by lazy { EventObservable<Any>( private val textChange by lazy { randomString() } private val errorMessage by lazy { randomString() } private val genericErrorMessage by lazy { randomString( private val invalidRequestErrorMessage by lazy { random private val noPermissionsErrorMessage by lazy { randomS engel.dev
AuthenticationRepository @MockK private lateinit var stringLoader: StringLoader @MockK private lateinit var telemetry: Telemetry @RelaxedMockK private lateinit var analytics: ActiveCampaignAnalytics private lateinit var subject: LoginViewModel private val viewStateAssertion = ViewStateAssertion<LoginViewModel.State>() private val accountTextChanges by lazy { EventObservable<CharSequence>() } private val usernameTextChanges by lazy { EventObservable<CharSequence>() } private val passwordTextChanges by lazy { EventObservable<CharSequence>() } private val domainTextChanges by lazy { EventObservable<CharSequence>() } private val loginClicks by lazy { EventObservable<Any>() } private val textChange by lazy { randomString() } private val errorMessage by lazy { randomString() } private val genericErrorMessage by lazy { randomString() } private val invalidRequestErrorMessage by lazy { randomString() } private val noPermissionsErrorMessage by lazy { randomString() } private val accountExpiredErrorMessage by lazy { randomString() } private val trace by lazy { mockk<Trace>() }
AuthenticationRepository @MockK private lateinit var stringLoader: StringLoader @MockK private lateinit var telemetry: Telemetry @RelaxedMockK private lateinit var analytics: ActiveCampaignAnalytics private lateinit var subject: LoginViewModel private val viewStateAssertion = ViewStateAssertion<LoginViewModel.State>() private val accountTextChanges by lazy { EventObservable<CharSequence>() } private val usernameTextChanges by lazy { EventObservable<CharSequence>() } private val passwordTextChanges by lazy { EventObservable<CharSequence>() } private val domainTextChanges by lazy { EventObservable<CharSequence>() } private val loginClicks by lazy { EventObservable<Any>() } private val textChange by lazy { randomString() } private val errorMessage by lazy { randomString() } private val genericErrorMessage by lazy { randomString() } private val invalidRequestErrorMessage by lazy { randomString() } private val noPermissionsErrorMessage by lazy { randomString() } private val accountExpiredErrorMessage by lazy { randomString() } private val trace by lazy { mockk<Trace>() } MockKAnnotations.init(this)
{ EventObservable<CharSequence>() } private val usernameTextChanges by lazy { EventObservable<CharSequence>() } private val passwordTextChanges by lazy { EventObservable<CharSequence>() } private val domainTextChanges by lazy { EventObservable<CharSequence>() } private val loginClicks by lazy { EventObservable<Any>() } private val textChange by lazy { randomString() } private val errorMessage by lazy { randomString() } private val genericErrorMessage by lazy { randomString() } private val invalidRequestErrorMessage by lazy { randomString() } private val noPermissionsErrorMessage by lazy { randomString() } private val accountExpiredErrorMessage by lazy { randomString() } private val trace by lazy { mockk<Trace>() } private fun prepareTelemetry() { every { telemetry.startTrace(any()) } returns trace every { trace.putAttribute(any(), any()) } just Runs every { telemetry.endTrace(trace) } just Runs }
{ EventObservable<CharSequence>() } private val usernameTextChanges by lazy { EventObservable<CharSequence>() } private val passwordTextChanges by lazy { EventObservable<CharSequence>() } private val domainTextChanges by lazy { EventObservable<CharSequence>() } private val loginClicks by lazy { EventObservable<Any>() } private val textChange by lazy { randomString() } private val errorMessage by lazy { randomString() } private val genericErrorMessage by lazy { randomString() } private val invalidRequestErrorMessage by lazy { randomString() } private val noPermissionsErrorMessage by lazy { randomString() } private val accountExpiredErrorMessage by lazy { randomString() } private val trace by lazy { mockk<Trace>() } private fun prepareTelemetry() { every { telemetry.startTrace(any()) } returns trace every { trace.putAttribute(any(), any()) } just Runs every { telemetry.endTrace(trace) } just Runs }
{ EventObservable<CharSequence>() } private val usernameTextChanges by lazy { EventObservable<CharSequence>() } private val passwordTextChanges by lazy { EventObservable<CharSequence>() } private val domainTextChanges by lazy { EventObservable<CharSequence>() } private val loginClicks by lazy { EventObservable<Any>() } private val textChange by lazy { randomString() } private val errorMessage by lazy { randomString() } private val genericErrorMessage by lazy { randomString() } private val invalidRequestErrorMessage by lazy { randomString() } private val noPermissionsErrorMessage by lazy { randomString() } private val accountExpiredErrorMessage by lazy { randomString() } private val trace by lazy { mockk<Trace>() } private fun prepareTelemetry() { every { telemetry.startTrace(any()) } returns trace every { trace.putAttribute(any(), any()) } just Runs every { telemetry.endTrace(trace) } just Runs }
{ EventObservable<CharSequence>() } s by lazy { EventObservable<CharSequence>() } by lazy { EventObservable<CharSequence>() } y { EventObservable<Any>() } { randomString() } zy { randomString() } e by lazy { randomString() } rMessage by lazy { randomString() } Message by lazy { randomString() } rMessage by lazy { randomString() } ckk<Trace>() } { ce(any()) } returns trace (any(), any()) } just Runs (trace) } just Runs /** * Generates a random string in the form of a [UUID]. */ fun randomString() = UUID.randomUUID().toString()
{ viewStateAssertion.assertFirstViewState { assertThat(it.loginSuccessful).isFalse() } } @Test fun `initial state should have loginEnabled set to false`() { viewStateAssertion.assertFirstViewState { assertThat(it.loginEnabled).isFalse() } } @Test fun `initial state should have loginForm set to empty values`() { viewStateAssertion.assertFirstViewState { assertThat(it.loginForm).isEqualTo(LoginViewModel.LoginForm()) } }
{ viewStateAssertion.assertFirstViewState { assertThat(it.loginSuccessful).isFalse() } } @Test fun `initial state should have loginEnabled set to false`() { viewStateAssertion.assertFirstViewState { assertThat(it.loginEnabled).isFalse() } } @Test fun `initial state should have loginForm set to empty values`() { viewStateAssertion.assertFirstViewState { assertThat(it.loginForm).isEqualTo(LoginViewModel.LoginForm()) } }