Skip to content

Commit

Permalink
Legg til Periode.krymp + tester
Browse files Browse the repository at this point in the history
  • Loading branch information
hestad committed Dec 2, 2024
1 parent ca26fb2 commit 6ad9b06
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 15 deletions.
1 change: 1 addition & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ Perioden kan ikke ha "hull" som ikke har en verdi
data class Periodisering<T>(
private val perioderMedVerdi: List<PeriodeMedVerdi<T>>,
) {
constructor(vararg periodeMedVerdi: PeriodeMedVerdi<T>) : this(periodeMedVerdi.toList())

constructor(
initiellVerdi: T,
totalePeriode: Periode,
) : this(PeriodeMedVerdi(initiellVerdi, totalePeriode))

init {
require(
perioderMedVerdi
Expand All @@ -22,22 +29,17 @@ data class Periodisering<T>(
) { "Ugyldig periodisering, for alle perioderMedVerdi gjelder at periode n+1 må starte dagen etter periode n slutter" }
}

val totalePeriode
get() =
Periode(
perioderMedVerdi.minOf { it.periode.fraOgMed },
perioderMedVerdi.maxOf { it.periode.tilOgMed },
)
val totalePeriode by lazy {
Periode(
perioderMedVerdi.minOf { it.periode.fraOgMed },
perioderMedVerdi.maxOf { it.periode.tilOgMed },
)
}

companion object {
operator fun <T> invoke(
initiellVerdi: T,
totalePeriode: Periode,
): Periodisering<T> =
Periodisering(
perioderMedVerdi =
listOf(PeriodeMedVerdi(initiellVerdi, totalePeriode)),
)
fun <T> empty(): Periodisering<T> {
return Periodisering(emptyList())
}

fun <T> List<Periodisering<T>>.reduser(sammensattVerdi: (T, T) -> T): Periodisering<T> {
require(this.isNotEmpty()) {
Expand All @@ -52,7 +54,8 @@ data class Periodisering<T>(

// Offentlig API:

fun slåSammenTilstøtendePerioder(): Periodisering<T> = this.copy(perioderMedVerdi = perioderMedVerdi.slåSammenTilstøtendePerioder())
fun slåSammenTilstøtendePerioder(): Periodisering<T> =
this.copy(perioderMedVerdi = perioderMedVerdi.slåSammenTilstøtendePerioder())

fun setVerdiForDelPeriode(
verdi: T,
Expand Down Expand Up @@ -151,6 +154,26 @@ data class Periodisering<T>(
)
}

fun krymp(
nyeTotalePeriode: Periode,
): Periodisering<T> {
if (nyeTotalePeriode == totalePeriode) {
// Optimalisering
return this
}
require(nyeTotalePeriode.fraOgMed >= totalePeriode.fraOgMed && nyeTotalePeriode.tilOgMed <= totalePeriode.tilOgMed) {
"Kan ikke krympe, ny periode $nyeTotalePeriode må ligge innenfor $totalePeriode"
}
val beholdte = perioderMedVerdi.mapNotNull { periodeMedVerdi ->
periodeMedVerdi.periode.overlappendePeriode(nyeTotalePeriode)?.let { overlappendePeriode ->
periodeMedVerdi.copy(periode = overlappendePeriode)
}
}
return this.copy(
perioderMedVerdi = beholdte.sortedBy { it.periode.fraOgMed },
)
}

/** Sjekker om alle verdiene er lik angitt verdi. */
fun inneholderKun(verdi: T): Boolean = perioderMedVerdi.all { it.verdi == verdi }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package no.nav.tiltakspenger.libs.periodisering

import io.kotest.assertions.throwables.shouldThrow
import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test
import java.time.LocalDate

class PeriodiseringKrympTest {
private val start = LocalDate.of(2024, 1, 1)
private val midt = LocalDate.of(2024, 6, 1)
private val slutt = LocalDate.of(2024, 12, 31)

@Test
fun `ny periode lik original periode`() {
val originalPeriode = Periode(start, slutt)
val verdi = "test"
val periodisering = Periodisering(verdi, originalPeriode)
periodisering.krymp(originalPeriode) shouldBe Periodisering(verdi, originalPeriode)
}

@Test
fun `krymping av av siste del av periode`() {
val originalPeriode = Periode(start, slutt)
val nyPeriode = Periode(midt, slutt)
val verdi = "test"
val periodisering = Periodisering(verdi, originalPeriode)
periodisering.krymp(nyPeriode) shouldBe Periodisering(verdi, nyPeriode)
}

@Test
fun `krymping av av første del av periode`() {
val originalPeriode = Periode(start, slutt)
val nyPeriode = Periode(start, midt)
val verdi = "test"
Periodisering(verdi, originalPeriode).krymp(nyPeriode) shouldBe Periodisering(verdi, nyPeriode)
}

@Test
fun `kan ikke utvide start`() {
val originalPeriode = Periode(start, slutt)
val nyPeriode = Periode(start.minusDays(1), midt)
val verdi = "test"
shouldThrow<IllegalArgumentException> {
Periodisering(verdi, originalPeriode).krymp(nyPeriode)
}.message shouldBe "Kan ikke krympe, ny periode Periode(fraOgMed=2023-12-31 tilOgMed=2024-06-01) må ligge innenfor Periode(fraOgMed=2024-01-01 tilOgMed=2024-12-31)"
}

@Test
fun `kan ikke utvide slutt`() {
val originalPeriode = Periode(start, slutt)
val nyPeriode = Periode(midt, slutt.plusDays(1))
val verdi = "test"
shouldThrow<IllegalArgumentException> {
Periodisering(verdi, originalPeriode).krymp(nyPeriode)
}.message shouldBe "Kan ikke krympe, ny periode Periode(fraOgMed=2024-06-01 tilOgMed=2025-01-01) må ligge innenfor Periode(fraOgMed=2024-01-01 tilOgMed=2024-12-31)"
}

@Test
fun `periodene har ingen overlapp`() {
val originalPeriode = Periode(start, midt)
val nyPeriode = Periode(midt.plusDays(1), slutt)
val verdi = "test"
val periodisering = Periodisering(verdi, originalPeriode)
shouldThrow<IllegalArgumentException> {
periodisering.krymp(nyPeriode)
}.message shouldBe "Kan ikke krympe, ny periode Periode(fraOgMed=2024-06-02 tilOgMed=2024-12-31) må ligge innenfor Periode(fraOgMed=2024-01-01 tilOgMed=2024-06-01)"
}

@Test
fun `krymper deler av første periode`() {
val periode1 = Periode(start, midt)
val periode2 = Periode(midt.plusDays(1), slutt)
val nyPeriode = Periode(midt, slutt)
val verdi1 = "v1"
val verdi2 = "v2"
val periodisering = Periodisering(
PeriodeMedVerdi(verdi1, periode1),
PeriodeMedVerdi(verdi2, periode2),
)
periodisering.krymp(nyPeriode) shouldBe Periodisering(
PeriodeMedVerdi(verdi1, Periode(midt, midt)),
PeriodeMedVerdi(verdi2, periode2),
)
}

@Test
fun `fjerner periode pga krymping`() {
val periode1 = Periode(start, midt)
val periode2 = Periode(midt.plusDays(1), slutt)
val nyPeriode = Periode(start.plusDays(1), midt.minusDays(1))
val verdi1 = "v1"
val verdi2 = "v2"
val periodisering = Periodisering(
PeriodeMedVerdi(verdi1, periode1),
PeriodeMedVerdi(verdi2, periode2),
)
periodisering.krymp(nyPeriode) shouldBe Periodisering(
PeriodeMedVerdi(verdi1, nyPeriode),
)
}
}

0 comments on commit 6ad9b06

Please sign in to comment.