Last active
July 11, 2019 10:24
-
-
Save abdallaadelessa/be04ef659941068ea3c75a314e24d27d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@file:UseExperimental(ExperimentalContracts::class) | |
package de.android.kotlin | |
import java.io.Serializable | |
import kotlin.contracts.ExperimentalContracts | |
import kotlin.contracts.contract | |
/** | |
* @author Created by Abdullah Essa on 2019-06-18. | |
*/ | |
//region Params | |
/** | |
* Wrapper class for 4 null safe parameters | |
*/ | |
data class FourParams<out A, out B, out C, out D>( | |
val first: A, | |
val second: B, | |
val third: C, | |
val fourth: D | |
) : Serializable { | |
companion object { | |
private const val serialVersionUID: Long = 1L | |
} | |
override fun toString(): String = "($first, $second, $third, $fourth)" | |
} | |
/** | |
* Converts this FourParams into a list. | |
*/ | |
fun <T> FourParams<T, T, T, T>.toList(): List<T> = listOf(first, second, third, fourth) | |
/** | |
* Wrapper class for 5 null safe parameters | |
*/ | |
data class FiveParams<out A, out B, out C, out D, out E>( | |
val first: A, | |
val second: B, | |
val third: C, | |
val fourth: D, | |
val fifth: E | |
) : Serializable { | |
companion object { | |
private const val serialVersionUID: Long = 1L | |
} | |
override fun toString(): String = "($first, $second, $third, $fourth, $fifth)" | |
} | |
/** | |
* Converts this FiveParams into a list. | |
*/ | |
fun <T> FiveParams<T, T, T, T, T>.toList(): List<T> = listOf(first, second, third, fourth, fifth) | |
//endregion | |
//region All | |
/** | |
* @return either a null safe [Pair] of the given parameters (if all of them are not null) | |
* or null if at least one of them is null | |
* | |
* ##Usage: | |
* | |
* val v1: Activity? = null | |
* val v2: Fragment? = null | |
* | |
* all(v1, v2) | |
* ?.let { (activity, fragment) -> | |
* activity.toString() | |
* fragment.toString() | |
* } | |
* | |
*/ | |
fun <A, B> all(first: A?, second: B?): Pair<A, B>? { | |
contract { | |
returnsNotNull() implies (first != null && second != null) | |
} | |
if (first == null || second == null) { | |
return null | |
} else { | |
return Pair(first, second) | |
} | |
} | |
/** | |
* @return either a null safe [Triple] of the given parameters (if all of them are not null) | |
* or null if at least one of them is null | |
* | |
* ##Usage: | |
* | |
* val v1: Activity? = null | |
* val v2: Fragment? = null | |
* val v3: Int? = null | |
* | |
* all(v1, v2, v3) | |
* ?.takeIf { (activity, fragment, intVar) -> !activity.isDestroyed && fragment.isAdded && intVar > 0 } | |
* ?.run { | |
* first.toString() | |
* second.toString() | |
* third.toString() | |
* } | |
* | |
*/ | |
fun <A, B, C> all(first: A?, second: B?, third: C?): Triple<A, B, C>? { | |
contract { | |
returnsNotNull() implies (first != null && second != null && third != null) | |
} | |
if (first == null || second == null || third == null) { | |
return null | |
} else { | |
return Triple(first, second, third) | |
} | |
} | |
/** | |
* @return either a null safe [FourParams] of the given parameters (if all of them are not null) | |
* or null if at least one of them is null | |
* | |
* ##Usage: | |
* | |
* val v1: Activity? = null | |
* val v2: Fragment? = null | |
* val v3: Int? = null | |
* val v4: String? = null | |
* | |
* all(v1, v2, v3, v4) | |
* ?.also { (activity, fragment, intVar, stringVar) -> | |
* activity.toString() | |
* fragment.toString() | |
* intVar.toString() | |
* stringVar.toString() | |
* } | |
* | |
*/ | |
@Suppress("ComplexCondition") | |
fun <A, B, C, D> all(first: A?, second: B?, third: C?, fourth: D?): FourParams<A, B, C, D>? { | |
contract { | |
returnsNotNull() implies (first != null && second != null && third != null && fourth != null) | |
} | |
if (first == null || second == null || third == null || fourth == null) { | |
return null | |
} else { | |
return FourParams(first, second, third, fourth) | |
} | |
} | |
/** | |
* @return either a null safe [FiveParams] of the given parameters (if all of them are not null) | |
* or null if at least one of them is null | |
* | |
* ##Usage: | |
* | |
* val v1: Activity? = null | |
* val v2: Fragment? = null | |
* val v3: Int? = null | |
* val v4: String? = null | |
* val v5: Boolean? = null | |
* | |
* all(v1, v2, v3, v4 ,v5) | |
* ?.apply { | |
* first.toString() | |
* second.toString() | |
* third.toString() | |
* fourth.toString() | |
* fifth.toString() | |
* } | |
* | |
*/ | |
@Suppress("ComplexCondition") | |
fun <A, B, C, D, E> all(first: A?, second: B?, third: C?, fourth: D?, fifth: E?): | |
FiveParams<A, B, C, D, E>? { | |
contract { | |
returnsNotNull() implies (first != null && second != null | |
&& third != null && fourth != null && fifth != null) | |
} | |
if (first == null || second == null || third == null || fourth == null || fifth == null) { | |
return null | |
} else { | |
return FiveParams(first, second, third, fourth, fifth) | |
} | |
} | |
/** | |
* @return either a null safe [List] of the given parameters (if all of them are not null) | |
* or null if at least one of them is null | |
* | |
* ##Usage: | |
* | |
* val v1: Activity? = null | |
* val v2: Fragment? = null | |
* val v3: Int? = null | |
* val v4: String? = null | |
* val v5: Boolean? = null | |
* | |
* allAsList(v1, v2, v3, v4 ,v5) | |
* ?.let { | |
* val first = it[0] as Activity | |
* val second = it[1] as Fragment | |
* val third = it[2] as Int | |
* val fourth = it[3] as String | |
* val fifth = it[4] as Boolean | |
* } | |
* | |
*/ | |
fun <T : Any> allAsList(vararg params: T?): List<T>? = | |
params.filterNotNull().takeIf { it.size == params.size } | |
//endregion | |
//region Mit | |
infix fun <A, B> A?.mit(other: B?) = all( | |
this, | |
other | |
) | |
infix fun <A, B, C> Pair<A?, B?>?.mit(other: C?) = all( | |
this?.first, | |
this?.second, | |
other | |
) | |
infix fun <A, B, C, D> Triple<A?, B?, C?>?.mit(other: D?) = all( | |
this?.first, | |
this?.second, | |
this?.third, | |
other | |
) | |
infix fun <A, B, C, D, E> FourParams<A?, B?, C?, D?>?.mit(other: E?) = all( | |
this?.first, | |
this?.second, | |
this?.third, | |
this?.fourth, | |
other | |
) | |
infix fun <A : Any, B : Any, C : Any, D : Any, E : Any, F : Any> FiveParams<A?, B?, C?, D?, E?>?.mit(other: F?) = | |
allAsList( | |
this?.first, | |
this?.second, | |
this?.third, | |
this?.fourth, | |
this?.fifth, | |
other | |
) | |
infix fun List<Any?>?.mit(other: Any?): List<Any>? { | |
if (this == null) return allAsList(other) | |
return allAsList(*this.toTypedArray(), other) | |
} | |
//endregion | |
fun main() { | |
val v1: Long? = 1L | |
val v2: Char? = 'a' | |
val v3: Int? = 1 | |
val v4: String? = "a" | |
val v5: Boolean? = true | |
all(v1, v2)?.let { (activity, fragment) -> | |
activity.toString() | |
fragment.toString() | |
} | |
if (all(v1, v2) != null) { | |
//Smart cast | |
v1.toString() | |
v2.toString() | |
} | |
//=========> | |
all(v1, v2, v3)?.run { | |
first.toString() | |
second.toString() | |
third.toString() | |
} | |
all(v1, v2, v3) | |
?.takeIf { (activity, fragment, intVar) -> intVar > 0 } | |
?.let { (first, second, third) -> | |
first.toString() | |
second.toString() | |
third.toString() | |
} | |
if (all(v1, v2, v3) != null) { | |
//Smart cast | |
v1.toString() | |
v2.toString() | |
v3.toString() | |
} | |
//=========> | |
all(v1, v2, v3, v4) | |
?.also { (activity, fragment, intVar, stringVar) -> | |
activity.toString() | |
fragment.toString() | |
intVar.toString() | |
stringVar.toString() | |
} | |
if (all(v1, v2, v3, v4) != null) { | |
//Smart cast | |
v1.toString() | |
v2.toString() | |
v3.toString() | |
v4.toString() | |
} | |
//=========> | |
all(v1, v2, v3, v4, v5) | |
?.apply { | |
first.toString() | |
second.toString() | |
third.toString() | |
fourth.toString() | |
fifth.toString() | |
} | |
if (all(v1, v2, v3, v4, v5) != null) { | |
//Smart cast | |
v1.toString() | |
v2.toString() | |
v3.toString() | |
v4.toString() | |
v5.toString() | |
} | |
//=========> | |
allAsList(v1, v2, v3, v4, v5) | |
?.let { | |
val first = it[0] as Long | |
val second = it[1] as Char | |
val third = it[2] as Int | |
val fourth = it[3] as String | |
val fifth = it[4] as Boolean | |
} | |
//=========> | |
(v1 mit v2)?.run { | |
first.toString() | |
second.toString() | |
} | |
(v1 mit v2 mit v3)?.run { | |
first.toString() | |
second.toString() | |
third.toString() | |
} | |
(v1 mit v2 mit v3 mit v4)?.run { | |
first.toString() | |
second.toString() | |
third.toString() | |
fourth.toString() | |
} | |
(v1 mit v2 mit v3 mit v4 mit v5)?.run { | |
first.toString() | |
second.toString() | |
third.toString() | |
fourth.toString() | |
fifth.toString() | |
} | |
(v1 mit v2 mit v3 mit v4 mit v5 mit v5 mit v5)?.run { | |
toString() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.android.kotlin | |
import android.app.Activity | |
import androidx.fragment.app.Fragment | |
import de.android.BaseUnitTest | |
import de.android.utils.tuples.FiveParams | |
import de.android.utils.tuples.FourParams | |
import de.android.utils.tuples.toList | |
import org.junit.Test | |
import org.mockito.Mockito.mock | |
import kotlin.contracts.ExperimentalContracts | |
import kotlin.test.assertNotNull | |
import kotlin.test.assertNull | |
import kotlin.test.assertTrue | |
/** | |
* @author Created by Abdullah Essa on 2019-06-18. | |
*/ | |
@ExperimentalContracts | |
class C24StandardTest : BaseUnitTest() { | |
private var v1: Activity? = null | |
private var v2: Fragment? = null | |
private var v3: Int? = null | |
private var v4: String? = null | |
private var v5: Boolean? = null | |
private var v6: Int? = null | |
private var v7: Int? = null | |
private var v8: Int? = null | |
override fun setUp() { | |
super.setUp() | |
v1 = null | |
v2 = null | |
v3 = null | |
v4 = null | |
v5 = null | |
v6 = null | |
v7 = null | |
v8 = null | |
} | |
@Test | |
fun testAllWithTwoNullParams() { | |
val all = all(v1, v2) | |
assertNull(all) | |
} | |
@Test | |
fun testAllWithTwoNotNullParams() { | |
v1 = mock(Activity::class.java) | |
v2 = mock(Fragment::class.java) | |
val all = all(v1, v2) | |
assertNotNull(all) | |
assertNotNull(all.first) | |
assertNotNull(all.second) | |
} | |
@Test | |
fun testAllWithThreeNullParams() { | |
val all = all(v1, v2, v3) | |
assertNull(all) | |
} | |
@Test | |
fun testAllWithThreeNotNullParams() { | |
v1 = mock(Activity::class.java) | |
v2 = mock(Fragment::class.java) | |
v3 = 1 | |
val all = all(v1, v2, v3) | |
assertNotNull(all) | |
assertNotNull(all.first) | |
assertNotNull(all.second) | |
assertNotNull(all.third) | |
} | |
@Test | |
fun testAllWithFourNullParams() { | |
val all = all(v1, v2, v3, v4) | |
assertNull(all) | |
} | |
@Test | |
fun testAllWithFourNotNullParams() { | |
v1 = mock(Activity::class.java) | |
v2 = mock(Fragment::class.java) | |
v3 = 1 | |
v4 = "" | |
val all = all(v1, v2, v3, v4) | |
assertNotNull(all) | |
assertNotNull(all.first) | |
assertNotNull(all.second) | |
assertNotNull(all.third) | |
assertNotNull(all.fourth) | |
} | |
@Test | |
fun testAllWithFiveNullParams() { | |
val all = all(v1, v2, v3, v4, v5) | |
assertNull(all) | |
} | |
@Test | |
fun testAllWithFiveNotNullParams() { | |
v1 = mock(Activity::class.java) | |
v2 = mock(Fragment::class.java) | |
v3 = 1 | |
v4 = "" | |
v5 = true | |
val all = all(v1, v2, v3, v4, v5) | |
assertNotNull(all) | |
assertNotNull(all.first) | |
assertNotNull(all.second) | |
assertNotNull(all.third) | |
assertNotNull(all.fourth) | |
assertNotNull(all.fifth) | |
} | |
@Test | |
fun testAllAsListWithNullableValues() { | |
val all = all(v1, v2, v3, v4, v5) | |
assertNull(all) | |
} | |
@Test | |
fun testAllAsListWithNotNullValues() { | |
v1 = mock(Activity::class.java) | |
v2 = mock(Fragment::class.java) | |
v3 = 1 | |
v4 = "" | |
v5 = true | |
v6 = 2 | |
v7 = 3 | |
v8 = 4 | |
val all = allAsList(v1, v2, v3, v4, v5, v6, v7, v8) | |
assertNotNull(all) | |
assertTrue { all.size == 8 } | |
assertTrue { all[0] == v1 } | |
assertTrue { all[1] == v2 } | |
assertTrue { all[2] == v3 } | |
assertTrue { all[3] == v4 } | |
assertTrue { all[4] == v5 } | |
assertTrue { all[5] == v6 } | |
assertTrue { all[6] == v7 } | |
assertTrue { all[7] == v8 } | |
} | |
@Test | |
fun testFourParamsToList() { | |
val v1 = 10 | |
val v2 = 20 | |
val v3 = 30 | |
val v4 = 40 | |
val fourParamsList = FourParams(v1, v2, v3, v4).toList() | |
val compareList = listOf(v1, v2, v3, v4) | |
assertTrue { fourParamsList.size == 4 } | |
assertTrue { fourParamsList[0] == compareList[0] } | |
assertTrue { fourParamsList[1] == compareList[1] } | |
assertTrue { fourParamsList[2] == compareList[2] } | |
assertTrue { fourParamsList[3] == compareList[3] } | |
} | |
@Test | |
fun testFiveParamsToList() { | |
val v1 = 10 | |
val v2 = 20 | |
val v3 = 30 | |
val v4 = 40 | |
val v5 = 50 | |
val fourParamsList = FiveParams(v1, v2, v3, v4, v5).toList() | |
val compareList = listOf(v1, v2, v3, v4, v5) | |
assertTrue { fourParamsList.size == 5 } | |
assertTrue { fourParamsList[0] == compareList[0] } | |
assertTrue { fourParamsList[1] == compareList[1] } | |
assertTrue { fourParamsList[2] == compareList[2] } | |
assertTrue { fourParamsList[3] == compareList[3] } | |
assertTrue { fourParamsList[4] == compareList[4] } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment