Skip to content
This repository has been archived by the owner on Aug 24, 2021. It is now read-only.

Commit

Permalink
fix: Missing values near boundary for instant and duration generators (
Browse files Browse the repository at this point in the history
…#229)

Thanks to @mmiikkkkaa
  • Loading branch information
mmiikkkkaa authored Oct 20, 2020
1 parent 6ed57fc commit 68a6fb9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public fun Generator.Companion.instants(
return Generator { random: Random ->
val seconds =
if (min.epochSecond == max.epochSecond) min.epochSecond
else random.nextLong(from = min.epochSecond, until = max.epochSecond)
// also include the max value (since "until" is not inclusive) by add 1
// (since Instant.MAX.epoch second is always lower than Long.MAX_VALUE there no overflow error possible)
else random.nextLong(from = min.epochSecond, until = max.epochSecond + 1)

val instant = Instant.ofEpochSecond(seconds)

Expand Down Expand Up @@ -79,7 +81,10 @@ public fun Generator.Companion.durations(
return Generator { random: Random ->
val seconds =
if (min.seconds == max.seconds) min.seconds
else random.nextLong(from = min.seconds, until = max.seconds)
// also include the max value (since "until" is not inclusive) by add 1,
// but only if Long.MAX_VALUE is not reached
else random.nextLong(from = min.seconds, until =
if (max.seconds == Long.MAX_VALUE) Long.MAX_VALUE else max.seconds + 1)

val duration = Duration.ofSeconds(seconds)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ class DurationGeneratorTest : AbstractGeneratorTest() {
val min = Duration.ofSeconds(1)
assertTrue(Generator.durations(min = min).randomSequence(0).take(50).any { it == min })
}

@Test
fun `generate durations with max seconds included`() {
val min = Duration.ofSeconds(1, MAX_NANOSECONDS - 2)
val max = Duration.ofSeconds(2, MAX_NANOSECONDS)
assertTrue(Generator.durations(min = min, max = max).randomSequence(0).take(50).filterNot { it == max }.any { it.seconds == max.seconds})
}

@Test
fun `do not created boundary errors if max seconds is long MAX_VALUE`() {
val min = Duration.ofSeconds(Long.MAX_VALUE - 1 )
val max = Duration.ofSeconds(Long.MAX_VALUE, MAX_NANOSECONDS)
assertTrue(Generator.durations(min = min, max = max).randomSequence(0).take(50).filterNot { it == max }.none { it.seconds == max.seconds })
}
}

class InstantGeneratorTest : AbstractGeneratorTest() {
Expand Down Expand Up @@ -161,6 +175,13 @@ class InstantGeneratorTest : AbstractGeneratorTest() {
assertTrue(Generator.instants(min = min, max = max).randomSequence(0).take(50).any { it == min })
}

@Test
fun `generate instants with max seconds included`() {
val min = Instant.ofEpochSecond(1)
val max = Instant.ofEpochSecond(2, MAX_NANOSECONDS)
assertTrue(Generator.instants(min = min, max = max).randomSequence(0).take(50).filterNot { it == max }.any { it.epochSecond == max.epochSecond })
}

@Test
fun `generate values within complete nanos range if epochsecond is not min boundary`() {
val minNanoBoundary = MAX_NANOSECONDS - 10
Expand All @@ -184,7 +205,6 @@ class InstantGeneratorTest : AbstractGeneratorTest() {
.filter { it.epochSecond < max.epochSecond }
.any { it.nano > maxNanoBoundary })
}

}

class LocalTimeGeneratorTest : AbstractGeneratorTest() {
Expand Down

0 comments on commit 68a6fb9

Please sign in to comment.