Update stdlib and tests (#1194)
This commit is contained in:
committed by
Nikolay Igotti
parent
2e07b3f52f
commit
670d05a4f3
@@ -0,0 +1,118 @@
|
||||
package test.ranges
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class CoercionTest {
|
||||
|
||||
@Test
|
||||
fun coercionsInt() {
|
||||
expect(5) { 5.coerceAtLeast(1) }
|
||||
expect(5) { 1.coerceAtLeast(5) }
|
||||
expect(1) { 5.coerceAtMost(1) }
|
||||
expect(1) { 1.coerceAtMost(5) }
|
||||
|
||||
for (value in 0..10) {
|
||||
expect(value) { value.coerceIn(null, null) }
|
||||
val min = 2
|
||||
val max = 5
|
||||
val range = min..max
|
||||
expect(value.coerceAtLeast(min)) { value.coerceIn(min, null) }
|
||||
expect(value.coerceAtMost(max)) { value.coerceIn(null, max) }
|
||||
expect(value.coerceAtLeast(min).coerceAtMost(max)) { value.coerceIn(min, max) }
|
||||
expect(value.coerceAtMost(max).coerceAtLeast(min)) { value.coerceIn(range) }
|
||||
assertTrue((value.coerceIn(range)) in range)
|
||||
}
|
||||
|
||||
assertFails { 1.coerceIn(1, 0) }
|
||||
assertFails { 1.coerceIn(1..0) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun coercionsLong() {
|
||||
expect(5L) { 5L.coerceAtLeast(1L) }
|
||||
expect(5L) { 1L.coerceAtLeast(5L) }
|
||||
expect(1L) { 5L.coerceAtMost(1L) }
|
||||
expect(1L) { 1L.coerceAtMost(5L) }
|
||||
|
||||
for (value in 0L..10L) {
|
||||
expect(value) { value.coerceIn(null, null) }
|
||||
val min = 2L
|
||||
val max = 5L
|
||||
val range = min..max
|
||||
expect(value.coerceAtLeast(min)) { value.coerceIn(min, null) }
|
||||
expect(value.coerceAtMost(max)) { value.coerceIn(null, max) }
|
||||
expect(value.coerceAtLeast(min).coerceAtMost(max)) { value.coerceIn(min, max) }
|
||||
expect(value.coerceAtMost(max).coerceAtLeast(min)) { value.coerceIn(range) }
|
||||
assertTrue((value.coerceIn(range)) in range)
|
||||
}
|
||||
|
||||
assertFails { 1L.coerceIn(1L, 0L) }
|
||||
assertFails { 1L.coerceIn(1L..0L) }
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun coercionsDouble() {
|
||||
expect(5.0) { 5.0.coerceAtLeast(1.0) }
|
||||
expect(5.0) { 1.0.coerceAtLeast(5.0) }
|
||||
assertTrue { Double.NaN.coerceAtLeast(1.0).isNaN() }
|
||||
|
||||
expect(1.0) { 5.0.coerceAtMost(1.0) }
|
||||
expect(1.0) { 1.0.coerceAtMost(5.0) }
|
||||
assertTrue { Double.NaN.coerceAtMost(5.0).isNaN() }
|
||||
|
||||
for (value in (0..10).map { it.toDouble() }) {
|
||||
expect(value) { value.coerceIn(null, null) }
|
||||
val min = 2.0
|
||||
val max = 5.0
|
||||
val range = min..max
|
||||
expect(value.coerceAtLeast(min)) { value.coerceIn(min, null) }
|
||||
expect(value.coerceAtMost(max)) { value.coerceIn(null, max) }
|
||||
expect(value.coerceAtLeast(min).coerceAtMost(max)) { value.coerceIn(min, max) }
|
||||
expect(value.coerceAtMost(max).coerceAtLeast(min)) { value.coerceIn(range) }
|
||||
assertTrue((value.coerceIn(range)) in range)
|
||||
}
|
||||
|
||||
assertFails { 1.0.coerceIn(1.0, 0.0) }
|
||||
assertFails { 1.0.coerceIn(1.0..0.0) }
|
||||
|
||||
assertTrue(0.0.equals(0.0.coerceIn(0.0, -0.0)))
|
||||
assertTrue((-0.0).equals((-0.0).coerceIn(0.0..-0.0)))
|
||||
|
||||
assertTrue(Double.NaN.coerceIn(0.0, 1.0).isNaN())
|
||||
assertTrue(Double.NaN.coerceIn(0.0..1.0).isNaN())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun coercionsComparable() {
|
||||
val v = (0..10).map { ComparableNumber(it) }
|
||||
|
||||
expect(5) { v[5].coerceAtLeast(v[1]).value }
|
||||
expect(5) { v[1].coerceAtLeast(v[5]).value }
|
||||
expect(v[5]) { v[5].coerceAtLeast(ComparableNumber(5)) }
|
||||
|
||||
expect(1) { v[5].coerceAtMost(v[1]).value }
|
||||
expect(1) { v[1].coerceAtMost(v[5]).value }
|
||||
expect(v[1]) { v[1].coerceAtMost(ComparableNumber(1)) }
|
||||
|
||||
for (value in v) {
|
||||
expect(value) { value.coerceIn(null, null) }
|
||||
val min = v[2]
|
||||
val max = v[5]
|
||||
val range = min..max
|
||||
expect(value.coerceAtLeast(min)) { value.coerceIn(min, null) }
|
||||
expect(value.coerceAtMost(max)) { value.coerceIn(null, max) }
|
||||
expect(value.coerceAtLeast(min).coerceAtMost(max)) { value.coerceIn(min, max) }
|
||||
expect(value.coerceAtMost(max).coerceAtLeast(min)) { value.coerceIn(range) }
|
||||
assertTrue((value.coerceIn(range)) in range)
|
||||
}
|
||||
|
||||
assertFails { v[1].coerceIn(v[1], v[0]) }
|
||||
assertFails { v[1].coerceIn(v[1]..v[0]) }
|
||||
}
|
||||
}
|
||||
|
||||
private class ComparableNumber(val value: Int) : Comparable<ComparableNumber> {
|
||||
override fun compareTo(other: ComparableNumber): Int = this.value - other.value
|
||||
override fun toString(): String = "CV$value"
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package test.ranges
|
||||
|
||||
import kotlin.comparisons.*
|
||||
import kotlin.test.*
|
||||
|
||||
|
||||
class ProgressionLastElementTest {
|
||||
|
||||
private val MAX = Int.MAX_VALUE
|
||||
private val MIN = Int.MIN_VALUE
|
||||
|
||||
private val INTERESTING = intArrayOf(MIN, MIN / 2, -239, -23, -1, 0, 1, 42, 239, MAX / 2, MAX)
|
||||
|
||||
private fun doTest(start: Int, end: Int, increment: Int, expected: Int) {
|
||||
|
||||
val actualInt = IntProgression.fromClosedRange(start, end, increment).last
|
||||
assertEquals(expected, actualInt)
|
||||
|
||||
val actualLong = LongProgression.fromClosedRange(start.toLong(), end.toLong(), increment.toLong()).last
|
||||
assertEquals(expected.toLong(), actualLong)
|
||||
}
|
||||
|
||||
@Test fun calculateFinalElement() {
|
||||
// start == end
|
||||
for (x in INTERESTING) {
|
||||
for (increment in INTERESTING)
|
||||
if (increment != 0) {
|
||||
doTest(x, x, increment, x)
|
||||
}
|
||||
}
|
||||
|
||||
// increment == 1
|
||||
for (start in INTERESTING.indices) {
|
||||
for (end in start..INTERESTING.size - 1) {
|
||||
doTest(INTERESTING[start], INTERESTING[end], 1, INTERESTING[end])
|
||||
}
|
||||
}
|
||||
|
||||
// increment == -1
|
||||
for (end in INTERESTING.indices) {
|
||||
for (start in end..INTERESTING.size - 1) {
|
||||
doTest(INTERESTING[start], INTERESTING[end], -1, INTERESTING[end])
|
||||
}
|
||||
}
|
||||
|
||||
// end == MAX
|
||||
doTest(0, MAX, MAX, MAX)
|
||||
doTest(0, MAX, MAX / 2, MAX - 1)
|
||||
doTest(MIN + 1, MAX, MAX, MAX)
|
||||
doTest(MAX - 7, MAX, 3, MAX - 1)
|
||||
doTest(MAX - 7, MAX, MAX, MAX - 7)
|
||||
|
||||
// end == MIN
|
||||
doTest(0, MIN, MIN, MIN)
|
||||
doTest(0, MIN, MIN / 2, MIN)
|
||||
doTest(MAX, MIN, MIN, -1)
|
||||
doTest(MIN + 7, MIN, -3, MIN + 1)
|
||||
doTest(MIN + 7, MIN, MIN, MIN + 7)
|
||||
}
|
||||
|
||||
@Test fun iterateToFinalElement() {
|
||||
// Small tests
|
||||
for (start in -5..4) {
|
||||
for (end in -5..4) {
|
||||
for (increment in -10..9) {
|
||||
// Cut down incorrect test data
|
||||
if (increment == 0) continue
|
||||
if (increment > 0 != start <= end) continue
|
||||
|
||||
// Iterate over the progression and obtain the expected result
|
||||
// println("$start,$end,$increment")
|
||||
var x = start
|
||||
while (true) {
|
||||
val next = x + increment
|
||||
if (next !in minOf(start, end)..maxOf(start, end)) break
|
||||
x = next
|
||||
}
|
||||
|
||||
doTest(start, end, increment, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package test.ranges
|
||||
|
||||
import test.collections.behaviors.iteratorBehavior
|
||||
import test.collections.compare
|
||||
import kotlin.test.*
|
||||
|
||||
public open class RangeIterationTestBase {
|
||||
public fun <N : Any> doTest(
|
||||
sequence: Iterable<N>,
|
||||
expectedFirst: N,
|
||||
expectedLast: N,
|
||||
expectedIncrement: Number,
|
||||
expectedElements: List<N>
|
||||
) {
|
||||
val first: Any
|
||||
val last: Any
|
||||
val increment: Number
|
||||
when (sequence) {
|
||||
is IntProgression -> {
|
||||
first = sequence.first
|
||||
last = sequence.last
|
||||
increment = sequence.step
|
||||
}
|
||||
is LongProgression -> {
|
||||
first = sequence.first
|
||||
last = sequence.last
|
||||
increment = sequence.step
|
||||
}
|
||||
is CharProgression -> {
|
||||
first = sequence.first
|
||||
last = sequence.last
|
||||
increment = sequence.step
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unsupported sequence type: $sequence")
|
||||
}
|
||||
|
||||
assertEquals(expectedFirst, first)
|
||||
assertEquals(expectedLast, last)
|
||||
assertEquals(expectedIncrement, increment)
|
||||
|
||||
if (expectedElements.isEmpty())
|
||||
assertTrue(sequence.none())
|
||||
else
|
||||
assertEquals(expectedElements, sequence.toList())
|
||||
|
||||
compare(expectedElements.iterator(), sequence.iterator()) {
|
||||
iteratorBehavior()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test data for codegen is generated from this class. If you change it, rerun GenerateTests
|
||||
public class RangeIterationTest : RangeIterationTestBase() {
|
||||
|
||||
@Test fun emptyConstant() {
|
||||
doTest(IntRange.EMPTY, 1, 0, 1, listOf())
|
||||
doTest(LongRange.EMPTY, 1.toLong(), 0.toLong(), 1.toLong(), listOf())
|
||||
|
||||
doTest(CharRange.EMPTY, 1.toChar(), 0.toChar(), 1, listOf())
|
||||
}
|
||||
|
||||
@Test fun emptyRange() {
|
||||
doTest(10..5, 10, 5, 1, listOf())
|
||||
doTest(10.toByte()..(-5).toByte(), 10, (-5), 1, listOf())
|
||||
doTest(10.toShort()..(-5).toShort(), 10, (-5), 1, listOf())
|
||||
doTest(10.toLong()..-5.toLong(), 10.toLong(), -5.toLong(), 1.toLong(), listOf())
|
||||
|
||||
doTest('z'..'a', 'z', 'a', 1, listOf())
|
||||
}
|
||||
|
||||
@Test fun oneElementRange() {
|
||||
doTest(5..5, 5, 5, 1, listOf(5))
|
||||
doTest(5.toByte()..5.toByte(), 5, 5, 1, listOf(5))
|
||||
doTest(5.toShort()..5.toShort(), 5, 5, 1, listOf(5))
|
||||
doTest(5.toLong()..5.toLong(), 5.toLong(), 5.toLong(), 1.toLong(), listOf(5.toLong()))
|
||||
|
||||
doTest('k'..'k', 'k', 'k', 1, listOf('k'))
|
||||
}
|
||||
|
||||
@Test fun simpleRange() {
|
||||
doTest(3..9, 3, 9, 1, listOf(3, 4, 5, 6, 7, 8, 9))
|
||||
doTest(3.toByte()..9.toByte(), 3, 9, 1, listOf(3, 4, 5, 6, 7, 8, 9))
|
||||
doTest(3.toShort()..9.toShort(), 3, 9, 1, listOf(3, 4, 5, 6, 7, 8, 9))
|
||||
doTest(3.toLong()..9.toLong(), 3.toLong(), 9.toLong(), 1.toLong(), listOf<Long>(3, 4, 5, 6, 7, 8, 9))
|
||||
|
||||
doTest('c'..'g', 'c', 'g', 1, listOf('c', 'd', 'e', 'f', 'g'))
|
||||
}
|
||||
|
||||
|
||||
@Test fun simpleRangeWithNonConstantEnds() {
|
||||
doTest((1 + 2)..(10 - 1), 3, 9, 1, listOf(3, 4, 5, 6, 7, 8, 9))
|
||||
doTest((1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte(), 3, 9, 1, listOf(3, 4, 5, 6, 7, 8, 9))
|
||||
doTest((1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort(), 3, 9, 1, listOf(3, 4, 5, 6, 7, 8, 9))
|
||||
doTest((1.toLong() + 2.toLong())..(10.toLong() - 1.toLong()), 3.toLong(), 9.toLong(), 1.toLong(), listOf<Long>(3, 4, 5, 6, 7, 8, 9))
|
||||
|
||||
doTest(("ace"[1])..("age"[1]), 'c', 'g', 1, listOf('c', 'd', 'e', 'f', 'g'))
|
||||
}
|
||||
|
||||
@Test fun openRange() {
|
||||
doTest(1 until 5, 1, 4, 1, listOf(1, 2, 3, 4))
|
||||
doTest(1.toByte() until 5.toByte(), 1, 4, 1, listOf(1, 2, 3, 4))
|
||||
doTest(1.toShort() until 5.toShort(), 1, 4, 1, listOf(1, 2, 3, 4))
|
||||
doTest(1.toLong() until 5.toLong(), 1L, 4L, 1L, listOf<Long>(1, 2, 3, 4))
|
||||
doTest('a' until 'd', 'a', 'c', 1, listOf('a', 'b', 'c'))
|
||||
}
|
||||
|
||||
|
||||
@Test fun emptyDownto() {
|
||||
doTest(5 downTo 10, 5, 10, -1, listOf())
|
||||
doTest(5.toByte() downTo 10.toByte(), 5, 10, -1, listOf())
|
||||
doTest(5.toShort() downTo 10.toShort(), 5, 10, -1, listOf())
|
||||
doTest(5.toLong() downTo 10.toLong(), 5.toLong(), 10.toLong(), -1.toLong(), listOf())
|
||||
|
||||
doTest('a' downTo 'z', 'a', 'z', -1, listOf())
|
||||
}
|
||||
|
||||
@Test fun oneElementDownTo() {
|
||||
doTest(5 downTo 5, 5, 5, -1, listOf(5))
|
||||
doTest(5.toByte() downTo 5.toByte(), 5, 5, -1, listOf(5))
|
||||
doTest(5.toShort() downTo 5.toShort(), 5, 5, -1, listOf(5))
|
||||
doTest(5.toLong() downTo 5.toLong(), 5.toLong(), 5.toLong(), -1.toLong(), listOf(5.toLong()))
|
||||
|
||||
doTest('k' downTo 'k', 'k', 'k', -1, listOf('k'))
|
||||
}
|
||||
|
||||
@Test fun simpleDownTo() {
|
||||
doTest(9 downTo 3, 9, 3, -1, listOf(9, 8, 7, 6, 5, 4, 3))
|
||||
doTest(9.toByte() downTo 3.toByte(), 9, 3, -1, listOf(9, 8, 7, 6, 5, 4, 3))
|
||||
doTest(9.toShort() downTo 3.toShort(), 9, 3, -1, listOf(9, 8, 7, 6, 5, 4, 3))
|
||||
doTest(9.toLong() downTo 3.toLong(), 9.toLong(), 3.toLong(), -1.toLong(), listOf<Long>(9, 8, 7, 6, 5, 4, 3))
|
||||
|
||||
doTest('g' downTo 'c', 'g', 'c', -1, listOf('g', 'f', 'e', 'd', 'c'))
|
||||
}
|
||||
|
||||
|
||||
@Test fun simpleSteppedRange() {
|
||||
doTest(3..9 step 2, 3, 9, 2, listOf(3, 5, 7, 9))
|
||||
doTest(3.toByte()..9.toByte() step 2, 3, 9, 2, listOf(3, 5, 7, 9))
|
||||
doTest(3.toShort()..9.toShort() step 2, 3, 9, 2, listOf(3, 5, 7, 9))
|
||||
doTest(3.toLong()..9.toLong() step 2.toLong(), 3.toLong(), 9.toLong(), 2.toLong(), listOf<Long>(3, 5, 7, 9))
|
||||
|
||||
doTest('c'..'g' step 2, 'c', 'g', 2, listOf('c', 'e', 'g'))
|
||||
}
|
||||
|
||||
@Test fun simpleSteppedDownTo() {
|
||||
doTest(9 downTo 3 step 2, 9, 3, -2, listOf(9, 7, 5, 3))
|
||||
doTest(9.toByte() downTo 3.toByte() step 2, 9, 3, -2, listOf(9, 7, 5, 3))
|
||||
doTest(9.toShort() downTo 3.toShort() step 2, 9, 3, -2, listOf(9, 7, 5, 3))
|
||||
doTest(9.toLong() downTo 3.toLong() step 2.toLong(), 9.toLong(), 3.toLong(), -2.toLong(), listOf<Long>(9, 7, 5, 3))
|
||||
|
||||
doTest('g' downTo 'c' step 2, 'g', 'c', -2, listOf('g', 'e', 'c'))
|
||||
}
|
||||
|
||||
|
||||
// 'inexact' means last element is not equal to sequence end
|
||||
@Test fun inexactSteppedRange() {
|
||||
doTest(3..8 step 2, 3, 7, 2, listOf(3, 5, 7))
|
||||
doTest(3.toByte()..8.toByte() step 2, 3, 7, 2, listOf(3, 5, 7))
|
||||
doTest(3.toShort()..8.toShort() step 2, 3, 7, 2, listOf(3, 5, 7))
|
||||
doTest(3.toLong()..8.toLong() step 2.toLong(), 3.toLong(), 7.toLong(), 2.toLong(), listOf<Long>(3, 5, 7))
|
||||
|
||||
doTest('a'..'d' step 2, 'a', 'c', 2, listOf('a', 'c'))
|
||||
}
|
||||
|
||||
// 'inexact' means last element is not equal to sequence end
|
||||
@Test fun inexactSteppedDownTo() {
|
||||
doTest(8 downTo 3 step 2, 8, 4, -2, listOf(8, 6, 4))
|
||||
doTest(8.toByte() downTo 3.toByte() step 2, 8, 4, -2, listOf(8, 6, 4))
|
||||
doTest(8.toShort() downTo 3.toShort() step 2, 8, 4, -2, listOf(8, 6, 4))
|
||||
doTest(8.toLong() downTo 3.toLong() step 2.toLong(), 8.toLong(), 4.toLong(), -2.toLong(), listOf<Long>(8, 6, 4))
|
||||
|
||||
doTest('d' downTo 'a' step 2, 'd', 'b', -2, listOf('d', 'b'))
|
||||
}
|
||||
|
||||
|
||||
@Test fun reversedEmptyRange() {
|
||||
doTest((5..3).reversed(), 3, 5, -1, listOf())
|
||||
doTest((5.toByte()..3.toByte()).reversed(), 3, 5, -1, listOf())
|
||||
doTest((5.toShort()..3.toShort()).reversed(), 3, 5, -1, listOf())
|
||||
doTest((5.toLong()..3.toLong()).reversed(), 3.toLong(), 5.toLong(), -1.toLong(), listOf())
|
||||
|
||||
doTest(('c'..'a').reversed(), 'a', 'c', -1, listOf())
|
||||
}
|
||||
|
||||
@Test fun reversedEmptyBackSequence() {
|
||||
doTest((3 downTo 5).reversed(), 5, 3, 1, listOf())
|
||||
doTest((3.toByte() downTo 5.toByte()).reversed(), 5, 3, 1, listOf())
|
||||
doTest((3.toShort() downTo 5.toShort()).reversed(), 5, 3, 1, listOf())
|
||||
doTest((3.toLong() downTo 5.toLong()).reversed(), 5.toLong(), 3.toLong(), 1.toLong(), listOf())
|
||||
|
||||
doTest(('a' downTo 'c').reversed(), 'c', 'a', 1, listOf())
|
||||
}
|
||||
|
||||
@Test fun reversedRange() {
|
||||
doTest((3..5).reversed(), 5, 3, -1, listOf(5, 4, 3))
|
||||
doTest((3.toByte()..5.toByte()).reversed(),5, 3, -1, listOf(5, 4, 3))
|
||||
doTest((3.toShort()..5.toShort()).reversed(), 5, 3, -1, listOf(5, 4, 3))
|
||||
doTest((3.toLong()..5.toLong()).reversed(), 5.toLong(), 3.toLong(), -1.toLong(), listOf<Long>(5, 4, 3))
|
||||
|
||||
doTest(('a'..'c').reversed(), 'c', 'a', -1, listOf('c', 'b', 'a'))
|
||||
}
|
||||
|
||||
@Test fun reversedBackSequence() {
|
||||
doTest((5 downTo 3).reversed(), 3, 5, 1, listOf(3, 4, 5))
|
||||
doTest((5.toByte() downTo 3.toByte()).reversed(), 3, 5, 1, listOf(3, 4, 5))
|
||||
doTest((5.toShort() downTo 3.toShort()).reversed(), 3, 5, 1, listOf(3, 4, 5))
|
||||
doTest((5.toLong() downTo 3.toLong()).reversed(), 3.toLong(), 5.toLong(), 1.toLong(), listOf<Long>(3, 4, 5))
|
||||
|
||||
doTest(('c' downTo 'a').reversed(), 'a', 'c', 1, listOf('a', 'b', 'c'))
|
||||
|
||||
}
|
||||
|
||||
@Test fun reversedSimpleSteppedRange() {
|
||||
doTest((3..9 step 2).reversed(), 9, 3, -2, listOf(9, 7, 5, 3))
|
||||
doTest((3.toByte()..9.toByte() step 2).reversed(), 9, 3, -2, listOf(9, 7, 5, 3))
|
||||
doTest((3.toShort()..9.toShort() step 2).reversed(), 9, 3, -2, listOf(9, 7, 5, 3))
|
||||
doTest((3.toLong()..9.toLong() step 2.toLong()).reversed(), 9.toLong(), 3.toLong(), -2.toLong(), listOf<Long>(9, 7, 5, 3))
|
||||
|
||||
doTest(('c'..'g' step 2).reversed(), 'g', 'c', -2, listOf('g', 'e', 'c'))
|
||||
}
|
||||
|
||||
// invariant progression.reversed().toList() == progression.toList().reversed() is preserved
|
||||
// 'inexact' means that start of reversed progression is not the end of original progression, but the last element
|
||||
@Test fun reversedInexactSteppedDownTo() {
|
||||
doTest((8 downTo 3 step 2).reversed(), 4, 8, 2, listOf(4, 6, 8))
|
||||
doTest((8.toByte() downTo 3.toByte() step 2).reversed(), 4, 8, 2, listOf(4, 6, 8))
|
||||
doTest((8.toShort() downTo 3.toShort() step 2).reversed(), 4, 8, 2, listOf(4, 6, 8))
|
||||
doTest((8.toLong() downTo 3.toLong() step 2.toLong()).reversed(), 4.toLong(), 8.toLong(), 2.toLong(), listOf<Long>(4, 6, 8))
|
||||
|
||||
doTest(('d' downTo 'a' step 2).reversed(), 'b', 'd', 2, listOf('b', 'd'))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
package test.ranges
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
public class RangeTest {
|
||||
@Test fun intRange() {
|
||||
val range = -5..9
|
||||
assertFalse(-1000 in range)
|
||||
assertFalse(-6 in range)
|
||||
|
||||
assertTrue(-5 in range)
|
||||
assertTrue(-4 in range)
|
||||
assertTrue(0 in range)
|
||||
assertTrue(3 in range)
|
||||
assertTrue(8 in range)
|
||||
assertTrue(9 in range)
|
||||
|
||||
assertFalse(10 in range)
|
||||
assertFalse(9000 in range)
|
||||
|
||||
assertFalse(range.isEmpty())
|
||||
|
||||
assertTrue(9 in (range as ClosedRange<Int>))
|
||||
assertFalse((range as ClosedRange<Int>).isEmpty())
|
||||
|
||||
assertTrue(1.toShort() in range)
|
||||
assertTrue(1.toByte() in range)
|
||||
assertTrue(1.toLong() in range)
|
||||
assertTrue(1.toFloat() in range)
|
||||
assertTrue(1.toDouble() in range)
|
||||
|
||||
assertFalse(Long.MAX_VALUE in range)
|
||||
|
||||
val openRange = 1 until 10
|
||||
assertTrue(9 in openRange)
|
||||
assertFalse(10 in openRange)
|
||||
|
||||
assertTrue((1 until Int.MIN_VALUE).isEmpty())
|
||||
}
|
||||
|
||||
@Test fun byteRange() {
|
||||
val range = (-5).toByte()..9.toByte()
|
||||
assertFalse((-100).toByte() in range)
|
||||
assertFalse((-6).toByte() in range)
|
||||
|
||||
assertTrue((-5).toByte() in range)
|
||||
assertTrue((-4).toByte() in range)
|
||||
assertTrue(0.toByte() in range)
|
||||
assertTrue(3.toByte() in range)
|
||||
assertTrue(8.toByte() in range)
|
||||
assertTrue(9.toByte() in range)
|
||||
|
||||
assertFalse(10.toByte() in range)
|
||||
assertFalse(111.toByte() in range)
|
||||
|
||||
assertFalse(range.isEmpty())
|
||||
|
||||
|
||||
assertTrue(1.toShort() in range)
|
||||
assertTrue(1.toInt() in range)
|
||||
assertTrue(1.toLong() in range)
|
||||
assertTrue(1.toFloat() in range)
|
||||
assertTrue(1.toDouble() in range)
|
||||
|
||||
assertFalse(Long.MAX_VALUE in range)
|
||||
|
||||
val openRange = 1.toByte() until 10.toByte()
|
||||
assertTrue(9.toByte() in openRange)
|
||||
assertFalse(10.toByte() in openRange)
|
||||
|
||||
// byte arguments now construct IntRange so no overflow here
|
||||
assertTrue((0.toByte() until Byte.MIN_VALUE).isEmpty())
|
||||
assertTrue((0.toByte() until Int.MIN_VALUE).isEmpty())
|
||||
}
|
||||
|
||||
@Test fun shortRange() {
|
||||
val range = (-5).toShort()..9.toShort()
|
||||
assertFalse((-1000).toShort() in range)
|
||||
assertFalse((-6).toShort() in range)
|
||||
|
||||
assertTrue((-5).toShort() in range)
|
||||
assertTrue((-4).toShort() in range)
|
||||
assertTrue(0.toShort() in range)
|
||||
assertTrue(3.toShort() in range)
|
||||
assertTrue(8.toShort() in range)
|
||||
assertTrue(9.toShort() in range)
|
||||
|
||||
assertFalse(10.toShort() in range)
|
||||
assertFalse(239.toShort() in range)
|
||||
|
||||
assertFalse(range.isEmpty())
|
||||
|
||||
assertTrue(1.toByte() in range)
|
||||
assertTrue(1.toInt() in range)
|
||||
assertTrue(1.toLong() in range)
|
||||
assertTrue(1.toFloat() in range)
|
||||
assertTrue(1.toDouble() in range)
|
||||
|
||||
assertFalse(Long.MAX_VALUE in range)
|
||||
|
||||
val openRange = 1.toShort() until 10.toShort()
|
||||
assertTrue(9.toShort() in openRange)
|
||||
assertFalse(10.toShort() in openRange)
|
||||
|
||||
assertTrue((0.toShort() until Short.MIN_VALUE).isEmpty())
|
||||
assertTrue((0.toShort() until Int.MIN_VALUE).isEmpty())
|
||||
}
|
||||
|
||||
@Test fun longRange() {
|
||||
val range = -5L..9L
|
||||
assertFalse(-10000000L in range)
|
||||
assertFalse(-6L in range)
|
||||
|
||||
assertTrue(-5L in range)
|
||||
assertTrue(-4L in range)
|
||||
assertTrue(0L in range)
|
||||
assertTrue(3L in range)
|
||||
assertTrue(8L in range)
|
||||
assertTrue(9L in range)
|
||||
|
||||
assertFalse(10L in range)
|
||||
assertFalse(10000000L in range)
|
||||
|
||||
assertFalse(range.isEmpty())
|
||||
|
||||
assertTrue(9 in (range as ClosedRange<Long>))
|
||||
assertFalse((range as ClosedRange<Long>).isEmpty())
|
||||
|
||||
assertTrue(1.toByte() in range)
|
||||
assertTrue(1.toShort() in range)
|
||||
assertTrue(1.toInt() in range)
|
||||
assertTrue(1.toFloat() in range)
|
||||
assertTrue(1.toDouble() in range)
|
||||
|
||||
assertFalse(Double.MAX_VALUE in range)
|
||||
|
||||
val openRange = 1L until 10L
|
||||
assertTrue(9L in openRange)
|
||||
assertFalse(10L in openRange)
|
||||
|
||||
assertTrue((0 until Long.MIN_VALUE).isEmpty())
|
||||
assertTrue((0L until Long.MIN_VALUE).isEmpty())
|
||||
|
||||
}
|
||||
|
||||
@Test fun charRange() {
|
||||
val range = 'c'..'w'
|
||||
assertFalse('0' in range)
|
||||
assertFalse('b' in range)
|
||||
|
||||
assertTrue('c' in range)
|
||||
assertTrue('d' in range)
|
||||
assertTrue('h' in range)
|
||||
assertTrue('m' in range)
|
||||
assertTrue('v' in range)
|
||||
assertTrue('w' in range)
|
||||
|
||||
assertFalse('z' in range)
|
||||
assertFalse('\u1000' in range)
|
||||
|
||||
assertFalse(range.isEmpty())
|
||||
|
||||
assertTrue('v' in (range as ClosedRange<Char>))
|
||||
assertFalse((range as ClosedRange<Char>).isEmpty())
|
||||
|
||||
val openRange = 'A' until 'Z'
|
||||
assertTrue('Y' in openRange)
|
||||
assertFalse('Z' in openRange)
|
||||
|
||||
assertTrue(('A' until '\u0000').isEmpty())
|
||||
}
|
||||
|
||||
@Test fun doubleRange() {
|
||||
val range = -1.0..3.14159265358979
|
||||
assertFalse(-1e200 in range)
|
||||
assertFalse(-100.0 in range)
|
||||
assertFalse(-1.00000000001 in range)
|
||||
|
||||
assertTrue(-1.0 in range)
|
||||
assertTrue(-0.99999999999 in range)
|
||||
assertTrue(0.0 in range)
|
||||
assertTrue(1.5 in range)
|
||||
assertTrue(3.1415 in range)
|
||||
assertTrue(3.14159265358979 in range)
|
||||
|
||||
assertFalse(3.15 in range)
|
||||
assertFalse(10.0 in range)
|
||||
assertFalse(1e200 in range)
|
||||
|
||||
assertFalse(range.isEmpty())
|
||||
|
||||
assertTrue(1.toByte() in range)
|
||||
assertTrue(1.toShort() in range)
|
||||
assertTrue(1.toInt() in range)
|
||||
assertTrue(1.toLong() in range)
|
||||
assertTrue(1.toFloat() in range)
|
||||
|
||||
val zeroRange = 0.0..-0.0
|
||||
assertFalse(zeroRange.isEmpty())
|
||||
assertTrue(-0.0 in zeroRange)
|
||||
assertTrue(-0.0F in zeroRange)
|
||||
val normalZeroRange = -0.0..0.0
|
||||
assertEquals(zeroRange, normalZeroRange)
|
||||
assertEquals(zeroRange.hashCode(), normalZeroRange.hashCode())
|
||||
|
||||
val nanRange = 0.0..Double.NaN
|
||||
assertFalse(1.0 in nanRange)
|
||||
assertFalse(Double.NaN in nanRange)
|
||||
assertFalse(Float.NaN in nanRange)
|
||||
assertTrue(nanRange.isEmpty())
|
||||
|
||||
val halfInfRange = 0.0..Double.POSITIVE_INFINITY
|
||||
assertTrue(Double.POSITIVE_INFINITY in halfInfRange)
|
||||
assertFalse(Double.NEGATIVE_INFINITY in halfInfRange)
|
||||
assertFalse(Double.NaN in halfInfRange)
|
||||
assertTrue(Float.POSITIVE_INFINITY in halfInfRange)
|
||||
}
|
||||
|
||||
@Test fun floatRange() {
|
||||
val range = -1.0f..3.14159f
|
||||
assertFalse(-1e30f in range)
|
||||
assertFalse(-100.0f in range)
|
||||
assertFalse(-1.00001f in range)
|
||||
|
||||
assertTrue(-1.0f in range)
|
||||
assertTrue(-0.99999f in range)
|
||||
assertTrue(0.0f in range)
|
||||
assertTrue(1.5f in range)
|
||||
assertTrue(3.1415f in range)
|
||||
assertTrue(3.14159f in range)
|
||||
|
||||
assertFalse(3.15f in range)
|
||||
assertFalse(10.0f in range)
|
||||
assertFalse(1e30f in range)
|
||||
|
||||
assertFalse(range.isEmpty())
|
||||
|
||||
assertTrue(1.toByte() in range)
|
||||
assertTrue(1.toShort() in range)
|
||||
assertTrue(1.toInt() in range)
|
||||
assertTrue(1.toLong() in range)
|
||||
assertTrue(1.toDouble() in range)
|
||||
|
||||
assertFalse(Double.MAX_VALUE in range)
|
||||
|
||||
val zeroRange = 0.0F..-0.0F
|
||||
assertFalse(zeroRange.isEmpty())
|
||||
assertTrue(-0.0F in zeroRange)
|
||||
val normalZeroRange = -0.0F..0.0F
|
||||
assertEquals(zeroRange, normalZeroRange)
|
||||
assertEquals(zeroRange.hashCode(), normalZeroRange.hashCode())
|
||||
|
||||
val nanRange = 0.0F..Float.NaN
|
||||
assertFalse(1.0F in nanRange)
|
||||
assertFalse(Float.NaN in nanRange)
|
||||
assertTrue(nanRange.isEmpty())
|
||||
|
||||
val halfInfRange = 0.0F..Float.POSITIVE_INFINITY
|
||||
assertTrue(Float.POSITIVE_INFINITY in halfInfRange)
|
||||
assertFalse(Float.NEGATIVE_INFINITY in halfInfRange)
|
||||
assertFalse(Float.NaN in halfInfRange)
|
||||
assertTrue(Double.POSITIVE_INFINITY in halfInfRange)
|
||||
assertTrue(Double.MAX_VALUE in halfInfRange)
|
||||
}
|
||||
|
||||
@Test fun isEmpty() {
|
||||
assertTrue((2..1).isEmpty())
|
||||
assertTrue((2L..0L).isEmpty())
|
||||
assertTrue((1.toShort()..-1.toShort()).isEmpty())
|
||||
assertTrue((0.toByte()..-1.toByte()).isEmpty())
|
||||
assertTrue((0f..-3.14f).isEmpty())
|
||||
assertTrue((-2.72..-3.14).isEmpty())
|
||||
assertTrue(('z'..'x').isEmpty())
|
||||
|
||||
assertTrue((1 downTo 2).isEmpty())
|
||||
assertTrue((0L downTo 2L).isEmpty())
|
||||
assertFalse((2 downTo 1).isEmpty())
|
||||
assertFalse((2L downTo 0L).isEmpty())
|
||||
assertTrue(('a' downTo 'z').isEmpty())
|
||||
assertTrue(('z'..'a' step 2).isEmpty())
|
||||
|
||||
assertTrue(("range".."progression").isEmpty())
|
||||
}
|
||||
|
||||
@Test fun emptyEquals() {
|
||||
assertTrue(IntRange.EMPTY == IntRange.EMPTY)
|
||||
assertEquals(IntRange.EMPTY, IntRange.EMPTY)
|
||||
assertEquals(0L..42L, 0L..42L)
|
||||
assertEquals(0L..4200000042000000L, 0L..4200000042000000L)
|
||||
assertEquals(3 downTo 0, 3 downTo 0)
|
||||
|
||||
assertEquals(2..1, 1..0)
|
||||
assertEquals(2L..1L, 1L..0L)
|
||||
assertEquals(2.toShort()..1.toShort(), 1.toShort()..0.toShort())
|
||||
assertEquals(2.toByte()..1.toByte(), 1.toByte()..0.toByte())
|
||||
assertEquals(0f..-3.14f, 3.14f..0f)
|
||||
assertEquals(-2.0..-3.0, 3.0..2.0)
|
||||
assertEquals('b'..'a', 'c'..'b')
|
||||
|
||||
assertTrue(1 downTo 2 == 2 downTo 3)
|
||||
assertTrue(-1L downTo 0L == -2L downTo -1L)
|
||||
assertEquals('j'..'a' step 4, 'u'..'q' step 2)
|
||||
|
||||
assertFalse(0..1 == IntRange.EMPTY)
|
||||
|
||||
assertEquals("range".."progression", "hashcode".."equals")
|
||||
assertFalse(("aa".."bb") == ("aaa".."bbb"))
|
||||
}
|
||||
|
||||
@Test fun emptyHashCode() {
|
||||
assertEquals((0..42).hashCode(), (0..42).hashCode())
|
||||
assertEquals((1.23..4.56).hashCode(), (1.23..4.56).hashCode())
|
||||
|
||||
assertEquals((0..-1).hashCode(), IntRange.EMPTY.hashCode())
|
||||
assertEquals((2L..1L).hashCode(), (1L..0L).hashCode())
|
||||
assertEquals((0.toShort()..-1.toShort()).hashCode(), (42.toShort()..0.toShort()).hashCode())
|
||||
assertEquals((0.toByte()..-1.toByte()).hashCode(), (42.toByte()..0.toByte()).hashCode())
|
||||
assertEquals((0f..-3.14f).hashCode(), (2.39f..1.41f).hashCode())
|
||||
assertEquals((0.0..-10.0).hashCode(), (10.0..0.0).hashCode())
|
||||
assertEquals(('z'..'x').hashCode(), ('l'..'k').hashCode())
|
||||
|
||||
assertEquals((1 downTo 2).hashCode(), (2 downTo 3).hashCode())
|
||||
assertEquals((1L downTo 2L).hashCode(), (2L downTo 3L).hashCode())
|
||||
assertEquals(('a' downTo 'b').hashCode(), ('c' downTo 'd').hashCode())
|
||||
|
||||
assertEquals(("range".."progression").hashCode(), ("hashcode".."equals").hashCode())
|
||||
}
|
||||
|
||||
@Test fun comparableRange() {
|
||||
val range = "island".."isle"
|
||||
assertFalse("apple" in range)
|
||||
assertFalse("icicle" in range)
|
||||
|
||||
assertTrue("island" in range)
|
||||
assertTrue("isle" in range)
|
||||
assertTrue("islandic" in range)
|
||||
|
||||
assertFalse("item" in range)
|
||||
assertFalse("trail" in range)
|
||||
|
||||
assertFalse(range.isEmpty())
|
||||
}
|
||||
|
||||
private fun assertFailsWithIllegalArgument(f: () -> Unit) = assertFailsWith<IllegalArgumentException> { f() }
|
||||
|
||||
@Test fun illegalProgressionCreation() {
|
||||
// create Progression explicitly with increment = 0
|
||||
assertFailsWithIllegalArgument { IntProgression.fromClosedRange(0, 5, 0) }
|
||||
assertFailsWithIllegalArgument { LongProgression.fromClosedRange(0, 5, 0) }
|
||||
assertFailsWithIllegalArgument { CharProgression.fromClosedRange('a', 'z', 0) }
|
||||
|
||||
|
||||
assertFailsWithIllegalArgument { 0..5 step 0 }
|
||||
assertFailsWithIllegalArgument { 0.toByte()..5.toByte() step 0 }
|
||||
assertFailsWithIllegalArgument { 0.toShort()..5.toShort() step 0 }
|
||||
assertFailsWithIllegalArgument { 0L..5L step 0L }
|
||||
assertFailsWithIllegalArgument { 'a'..'z' step 0 }
|
||||
|
||||
assertFailsWithIllegalArgument { 0 downTo -5 step 0 }
|
||||
assertFailsWithIllegalArgument { 0.toByte() downTo -5.toByte() step 0 }
|
||||
assertFailsWithIllegalArgument { 0.toShort() downTo -5.toShort() step 0 }
|
||||
assertFailsWithIllegalArgument { 0L downTo -5L step 0L }
|
||||
assertFailsWithIllegalArgument { 'z' downTo 'a' step 0 }
|
||||
|
||||
assertFailsWithIllegalArgument { 0..5 step -2 }
|
||||
assertFailsWithIllegalArgument { 0.toByte()..5.toByte() step -2 }
|
||||
assertFailsWithIllegalArgument { 0.toShort()..5.toShort() step -2 }
|
||||
assertFailsWithIllegalArgument { 0L..5L step -2L }
|
||||
assertFailsWithIllegalArgument { 'a'..'z' step -2 }
|
||||
|
||||
|
||||
assertFailsWithIllegalArgument { 0 downTo -5 step -2 }
|
||||
assertFailsWithIllegalArgument { 0.toByte() downTo -5.toByte() step -2 }
|
||||
assertFailsWithIllegalArgument { 0.toShort() downTo -5.toShort() step -2 }
|
||||
assertFailsWithIllegalArgument { 0L downTo -5L step -2L }
|
||||
assertFailsWithIllegalArgument { 'z' downTo 'a' step -2 }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user