Fix array iterators to adhere to Iterator contract

#KT-17453 Fixed

Change expected exceptions in tests.
This commit is contained in:
Ilya Gorbunov
2017-04-17 23:49:43 +03:00
parent 2380e0bacc
commit 4a5d8534c1
6 changed files with 46 additions and 28 deletions
+8 -8
View File
@@ -19,7 +19,7 @@ fun box(): String {
assertEquals(true, booleanArrayOf(true).iterator().nextBoolean())
assertEquals(true, booleanArrayOf(true).iterator().next())
assertFalse(booleanArrayOf().iterator().hasNext())
assertTrue(assertFails { booleanArrayOf().iterator().next() } is IndexOutOfBoundsException)
assertTrue(assertFails { booleanArrayOf().iterator().next() } is NoSuchElementException)
assertTrue(eqByte(byteArrayOf(0), ByteArray(1)))
assertTrue(eqByte(byteArrayOf(1, 2, 3), ByteArray(3) { (it + 1).toByte() }))
@@ -34,7 +34,7 @@ fun box(): String {
assertEquals(1, byteArrayOf(1).iterator().nextByte())
assertEquals(1, byteArrayOf(1).iterator().next())
assertFalse(byteArrayOf().iterator().hasNext())
assertTrue(assertFails { byteArrayOf().iterator().next() } is IndexOutOfBoundsException)
assertTrue(assertFails { byteArrayOf().iterator().next() } is NoSuchElementException)
assertTrue(eqShort(shortArrayOf(0), ShortArray(1)))
assertTrue(eqShort(shortArrayOf(1, 2, 3), ShortArray(3) { (it + 1).toShort() }))
@@ -49,7 +49,7 @@ fun box(): String {
assertEquals(1, shortArrayOf(1).iterator().nextShort())
assertEquals(1, shortArrayOf(1).iterator().next())
assertFalse(shortArrayOf().iterator().hasNext())
assertTrue(assertFails { shortArrayOf().iterator().next() } is IndexOutOfBoundsException)
assertTrue(assertFails { shortArrayOf().iterator().next() } is NoSuchElementException)
assertTrue(eqChar(charArrayOf(0.toChar()), CharArray(1)))
assertTrue(eqChar(charArrayOf('a', 'b', 'c'), CharArray(3) { 'a' + it }))
@@ -64,7 +64,7 @@ fun box(): String {
assertEquals('a', charArrayOf('a').iterator().nextChar())
assertEquals('a', charArrayOf('a').iterator().next())
assertFalse(charArrayOf().iterator().hasNext())
assertTrue(assertFails { charArrayOf().iterator().next() } is IndexOutOfBoundsException)
assertTrue(assertFails { charArrayOf().iterator().next() } is NoSuchElementException)
assertTrue(eqInt(intArrayOf(0), IntArray(1)))
assertTrue(eqInt(intArrayOf(1, 2, 3), IntArray(3) { it + 1 }))
@@ -79,7 +79,7 @@ fun box(): String {
assertEquals(1, intArrayOf(1).iterator().nextInt())
assertEquals(1, intArrayOf(1).iterator().next())
assertFalse(intArrayOf().iterator().hasNext())
assertTrue(assertFails { intArrayOf().iterator().next() } is IndexOutOfBoundsException)
assertTrue(assertFails { intArrayOf().iterator().next() } is NoSuchElementException)
assertTrue(eqFloat(floatArrayOf(0f), FloatArray(1)))
assertTrue(eqFloat(floatArrayOf(1f, 2f, 3f), FloatArray(3) { (it + 1).toFloat() }))
@@ -94,7 +94,7 @@ fun box(): String {
assertEquals(1f, floatArrayOf(1f).iterator().nextFloat())
assertEquals(1f, floatArrayOf(1f).iterator().next())
assertFalse(floatArrayOf().iterator().hasNext())
assertTrue(assertFails { floatArrayOf().iterator().next() } is IndexOutOfBoundsException)
assertTrue(assertFails { floatArrayOf().iterator().next() } is NoSuchElementException)
assertTrue(eqDouble(doubleArrayOf(0.0), DoubleArray(1)))
assertTrue(eqDouble(doubleArrayOf(1.0, 2.0, 3.0), DoubleArray(3) { (it + 1).toDouble() }))
@@ -109,7 +109,7 @@ fun box(): String {
assertEquals(1.0, doubleArrayOf(1.0).iterator().nextDouble())
assertEquals(1.0, doubleArrayOf(1.0).iterator().next())
assertFalse(doubleArrayOf().iterator().hasNext())
assertTrue(assertFails { doubleArrayOf().iterator().next() } is IndexOutOfBoundsException)
assertTrue(assertFails { doubleArrayOf().iterator().next() } is NoSuchElementException)
assertTrue(eqLong(longArrayOf(0), LongArray(1)))
assertTrue(eqLong(longArrayOf(1, 2, 3), LongArray(3) { it + 1L }))
@@ -124,7 +124,7 @@ fun box(): String {
assertEquals(1L, longArrayOf(1).iterator().nextLong())
assertEquals(1L, longArrayOf(1).iterator().next())
assertFalse(longArrayOf().iterator().hasNext())
assertTrue(assertFails { longArrayOf().iterator().next() } is IndexOutOfBoundsException)
assertTrue(assertFails { longArrayOf().iterator().next() } is NoSuchElementException)
// If `is` checks work...
if (intArrayOf() is IntArray) {
@@ -19,7 +19,7 @@ package kotlin.jvm.internal
private class ArrayIterator<T>(val array: Array<T>) : Iterator<T> {
private var index = 0
override fun hasNext() = index < array.size
override fun next() = array[index++]
override fun next() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
public fun <T> iterator(array: Array<T>): Iterator<T> = ArrayIterator(array)
@@ -21,49 +21,49 @@ package kotlin.jvm.internal
private class ArrayByteIterator(private val array: ByteArray) : ByteIterator() {
private var index = 0
override fun hasNext() = index < array.size
override fun nextByte() = array[index++]
override fun nextByte() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
private class ArrayCharIterator(private val array: CharArray) : CharIterator() {
private var index = 0
override fun hasNext() = index < array.size
override fun nextChar() = array[index++]
override fun nextChar() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
private class ArrayShortIterator(private val array: ShortArray) : ShortIterator() {
private var index = 0
override fun hasNext() = index < array.size
override fun nextShort() = array[index++]
override fun nextShort() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
private class ArrayIntIterator(private val array: IntArray) : IntIterator() {
private var index = 0
override fun hasNext() = index < array.size
override fun nextInt() = array[index++]
override fun nextInt() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
private class ArrayLongIterator(private val array: LongArray) : LongIterator() {
private var index = 0
override fun hasNext() = index < array.size
override fun nextLong() = array[index++]
override fun nextLong() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
private class ArrayFloatIterator(private val array: FloatArray) : FloatIterator() {
private var index = 0
override fun hasNext() = index < array.size
override fun nextFloat() = array[index++]
override fun nextFloat() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
private class ArrayDoubleIterator(private val array: DoubleArray) : DoubleIterator() {
private var index = 0
override fun hasNext() = index < array.size
override fun nextDouble() = array[index++]
override fun nextDouble() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
private class ArrayBooleanIterator(private val array: BooleanArray) : BooleanIterator() {
private var index = 0
override fun hasNext() = index < array.size
override fun nextBoolean() = array[index++]
override fun nextBoolean() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }
}
public fun iterator(array: ByteArray): ByteIterator = ArrayByteIterator(array)
@@ -29,7 +29,7 @@ class GenerateArrayIterators(out: PrintWriter) : BuiltInsSourceGenerator(out) {
out.println("private class Array${s}Iterator(private val array: ${s}Array) : ${s}Iterator() {")
out.println(" private var index = 0")
out.println(" override fun hasNext() = index < array.size")
out.println(" override fun next$s() = array[index++]")
out.println(" override fun next$s() = try { array[index++] } catch (e: ArrayIndexOutOfBoundsException) { throw NoSuchElementException(e.message) }")
out.println("}")
out.println()
}
+9 -9
View File
@@ -21,7 +21,7 @@ internal fun arrayIterator(array: dynamic, type: String?) = when (type) {
object : Iterator<dynamic> {
var index = 0
override fun hasNext() = index < arr.size
override fun next() = if (index < arr.size) arr[index++] else throw IndexOutOfBoundsException("$index")
override fun next() = if (index < arr.size) arr[index++] else throw NoSuchElementException("$index")
}
}
"BooleanArray" -> booleanArrayIterator(array)
@@ -39,56 +39,56 @@ internal fun arrayIterator(array: dynamic, type: String?) = when (type) {
internal fun booleanArrayIterator(array: BooleanArray) = object : BooleanIterator() {
var index = 0
override fun hasNext() = index < array.size
override fun nextBoolean() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
override fun nextBoolean() = if (index < array.size) array[index++] else throw NoSuchElementException("$index")
}
@JsName("byteArrayIterator")
internal fun byteArrayIterator(array: ByteArray) = object : ByteIterator() {
var index = 0
override fun hasNext() = index < array.size
override fun nextByte() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
override fun nextByte() = if (index < array.size) array[index++] else throw NoSuchElementException("$index")
}
@JsName("shortArrayIterator")
internal fun shortArrayIterator(array: ShortArray) = object : ShortIterator() {
var index = 0
override fun hasNext() = index < array.size
override fun nextShort() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
override fun nextShort() = if (index < array.size) array[index++] else throw NoSuchElementException("$index")
}
@JsName("charArrayIterator")
internal fun charArrayIterator(array: CharArray) = object : CharIterator() {
var index = 0
override fun hasNext() = index < array.size
override fun nextChar() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
override fun nextChar() = if (index < array.size) array[index++] else throw NoSuchElementException("$index")
}
@JsName("intArrayIterator")
internal fun intArrayIterator(array: IntArray) = object : IntIterator() {
var index = 0
override fun hasNext() = index < array.size
override fun nextInt() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
override fun nextInt() = if (index < array.size) array[index++] else throw NoSuchElementException("$index")
}
@JsName("floatArrayIterator")
internal fun floatArrayIterator(array: FloatArray) = object : FloatIterator() {
var index = 0
override fun hasNext() = index < array.size
override fun nextFloat() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
override fun nextFloat() = if (index < array.size) array[index++] else throw NoSuchElementException("$index")
}
@JsName("doubleArrayIterator")
internal fun doubleArrayIterator(array: DoubleArray) = object : DoubleIterator() {
var index = 0
override fun hasNext() = index < array.size
override fun nextDouble() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
override fun nextDouble() = if (index < array.size) array[index++] else throw NoSuchElementException("$index")
}
@JsName("longArrayIterator")
internal fun longArrayIterator(array: LongArray) = object : LongIterator() {
var index = 0
override fun hasNext() = index < array.size
override fun nextLong() = if (index < array.size) array[index++] else throw IndexOutOfBoundsException("$index")
override fun nextLong() = if (index < array.size) array[index++] else throw NoSuchElementException("$index")
}
@JsName("PropertyMetadata")
@@ -16,7 +16,7 @@
package test.collections
import test.collections.behaviors.listBehavior
import test.collections.behaviors.*
import test.comparisons.STRING_CASE_INSENSITIVE_ORDER
import kotlin.test.*
import org.junit.Test
@@ -636,6 +636,24 @@ class ArraysTest {
assertArrayNotSameButEquals(booleanArrayOf(true, false, true), booleanArrayOf(true, false, true, true).sliceArray(coll))
}
@Test fun iterators() {
fun <T, E> checkContract(array: T, toList: T.() -> List<E>, iterator: T.() -> Iterator<E>) =
compare(array.toList().iterator(), array.iterator()) {
iteratorBehavior()
}
checkContract(arrayOf("a", "b", "c"), { toList() }, { iterator() })
checkContract(intArrayOf(), { toList() }, { iterator() })
checkContract(intArrayOf(1, 2, 3), { toList() }, { iterator() })
checkContract(shortArrayOf(1, 2, 3), { toList() }, { iterator() })
checkContract(byteArrayOf(1, 2, 3), { toList() }, { iterator() })
checkContract(longArrayOf(1L, 2L, 3L), { toList() }, { iterator() })
checkContract(doubleArrayOf(2.0, 3.0, 9.0), { toList() }, { iterator() })
checkContract(floatArrayOf(2f, 3f, 9f), { toList() }, { iterator() })
checkContract(charArrayOf('a', 'b', 'c'), { toList() }, { iterator() })
checkContract(booleanArrayOf(true, false), { toList() }, { iterator() })
}
@Test fun asIterable() {
val arr1 = intArrayOf(1, 2, 3, 4, 5)
val iter1 = arr1.asIterable()