blob: 4298a4d3b74184317907e01ebc319f0af2e9c188 [file] [log] [blame]
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'))
}
}