Skip to content

Commit

Permalink
MF-171: Replace argThat with eager failures
Browse files Browse the repository at this point in the history
argThat is not descriptive enough for composite conditions.
  • Loading branch information
stoyicker committed Aug 30, 2024
1 parent 1d9ad7f commit 5cf2923
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 184 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,46 @@ package com.tidal.sdk.player.playlog

import assertk.Assert
import assertk.assertions.isCloseTo
import kotlin.math.absoluteValue
import junit.framework.AssertionFailedError

internal fun Assert<Double>.isAssetPositionEqualTo(targetPosition: Double) =
isCloseTo(targetPosition, 0.5)

internal fun Double.isAssetPositionEqualTo(targetPosition: Double) =
(this - targetPosition).absoluteValue < 0.5
@Suppress("ThrowsCount")
internal fun <T> Iterable<T>.combinedPassAllOf(
vararg checks: Pair<Int, T.() -> Unit>,
) {
val passesLeft = checks.map { it.first }.toMutableList()
val throwableMessageMap = mutableMapOf<Int, MutableList<String>>()
forEachIndexed { subjectIndex, subject ->
var checkIndex = -1
while (checkIndex < checks.size) {
try {
val check = checks[++checkIndex].second
subject.check()
if (passesLeft[checkIndex] <= 0) {
throw AssertionFailedError(
"Check at index $checkIndex passed more than desired amount of times (${checks[checkIndex].first})" // ktlint-disable max-line-length
)
}
passesLeft[checkIndex]--
throwableMessageMap.remove(subjectIndex)
checkIndex = checks.size
} catch (throwable: Throwable) {
if (!throwableMessageMap.containsKey(subjectIndex)) {
throwableMessageMap[subjectIndex] = mutableListOf()
}
throwableMessageMap.getValue(subjectIndex).add(throwable.message!!)
}
}
}
if (throwableMessageMap.isNotEmpty()) {
throw AssertionFailedError("Failed check(s): $throwableMessageMap")
}
val index = passesLeft.indexOfFirst { it != 0 }
if (index != -1) {
throw AssertionFailedError(
"Missed check: index $index, wanted ${checks[index].first}, missed ${passesLeft[index]}"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import org.mockito.Mockito.times
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.argThat
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
import org.mockito.kotlin.verify

Expand Down Expand Up @@ -830,6 +831,7 @@ internal class SingleMediaProductPlayLogTest {
@Test
fun seekBeyondBoundsWithRepeatOne() = runTest {
val gson = Gson()
val payloadCaptor = argumentCaptor<String>()

player.playbackEngine.load(mediaProduct)
player.playbackEngine.setRepeatOne(true)
Expand All @@ -848,51 +850,48 @@ internal class SingleMediaProductPlayLogTest {
}

eventReporterCoroutineScope.advanceUntilIdle()
verify(eventSender).sendEvent(
verify(eventSender, times(2)).sendEvent(
eq("playback_session"),
eq(ConsentCategory.NECESSARY),
argThat {
with(gson.fromJson(this, JsonObject::class.java)["payload"].asJsonObject) {
get("startAssetPosition").asDouble.isAssetPositionEqualTo(0.0) &&
get("endAssetPosition").asDouble
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS) &&
get("actualProductId")?.asString.contentEquals(mediaProduct.productId) &&
get("sourceType")?.asString.contentEquals(mediaProduct.sourceType) &&
get("sourceId")?.asString.contentEquals(mediaProduct.sourceId) &&
get("actions").asJsonArray.run {
val stopAction =
gson.fromJson(this[0], PlaybackSession.Payload.Action::class.java)
val startAction =
gson.fromJson(this[1], PlaybackSession.Payload.Action::class.java)
val perfectResumeTimestamp = stopAction.timestamp
stopAction.actionType ==
PlaybackSession.Payload.Action.Type.PLAYBACK_STOP &&
stopAction.assetPositionSeconds.isAssetPositionEqualTo(2.0) &&
startAction.actionType ==
PlaybackSession.Payload.Action.Type.PLAYBACK_START &&
startAction.assetPositionSeconds
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS) &&
startAction.timestamp in
(perfectResumeTimestamp - 500)..(perfectResumeTimestamp + 500)
}
}
},
payloadCaptor.capture(),
eq(emptyMap()),
)
verify(eventSender).sendEvent(
eq("playback_session"),
eq(ConsentCategory.NECESSARY),
argThat {
with(gson.fromJson(this, JsonObject::class.java)["payload"].asJsonObject) {
get("startAssetPosition").asDouble.isAssetPositionEqualTo(0.0) &&
get("endAssetPosition").asDouble.isAssetPositionEqualTo(1.0) &&
get("actualProductId")?.asString.contentEquals(mediaProduct.productId) &&
get("sourceType")?.asString.contentEquals(mediaProduct.sourceType) &&
get("sourceId")?.asString.contentEquals(mediaProduct.sourceId) &&
get("actions").asJsonArray.isEmpty
payloadCaptor.allValues.map {
gson.fromJson(it, JsonObject::class.java)["payload"].asJsonObject
}.combinedPassAllOf(
1 to {
assertThat(get("startAssetPosition").asDouble).isAssetPositionEqualTo(0.0)
assertThat(get("endAssetPosition").asDouble)
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS)
assertThat(get("actualProductId")?.asString)
.isEqualTo(mediaProduct.productId)
assertThat(get("sourceType")?.asString).isEqualTo(mediaProduct.sourceType)
assertThat(get("sourceId")?.asString).isEqualTo(mediaProduct.sourceId)
with(get("actions").asJsonArray) {
val stopAction =
gson.fromJson(this[0], PlaybackSession.Payload.Action::class.java)
val startAction =
gson.fromJson(this[1], PlaybackSession.Payload.Action::class.java)
val perfectResumeTimestamp = stopAction.timestamp
assertThat(stopAction.actionType)
.isEqualTo(PlaybackSession.Payload.Action.Type.PLAYBACK_STOP)
assertThat(stopAction.assetPositionSeconds).isAssetPositionEqualTo(2.0)
assertThat(startAction.actionType)
.isEqualTo(PlaybackSession.Payload.Action.Type.PLAYBACK_START)
assertThat(startAction.assetPositionSeconds)
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS)
assertThat(startAction.timestamp)
.isBetween(perfectResumeTimestamp - 500, perfectResumeTimestamp + 500)
}
},
eq(emptyMap()),
1 to {
assertThat(get("startAssetPosition").asDouble).isAssetPositionEqualTo(0.0)
assertThat(get("endAssetPosition").asDouble).isAssetPositionEqualTo(1.0)
assertThat(get("actualProductId")?.asString).isEqualTo(mediaProduct.productId)
assertThat(get("sourceType")?.asString).isEqualTo(mediaProduct.sourceType)
assertThat(get("sourceId")?.asString).isEqualTo(mediaProduct.sourceId)
assertThat(get("actions").asJsonArray).isEmpty()
},
)
}
}
Expand Down
Loading

0 comments on commit 5cf2923

Please sign in to comment.