diff --git a/anko/library/robolectricTests/src/test/java/SparseArraysTest b/anko/library/robolectricTests/src/test/java/SparseArraysTest new file mode 100644 index 00000000..a92fd426 --- /dev/null +++ b/anko/library/robolectricTests/src/test/java/SparseArraysTest @@ -0,0 +1,95 @@ +package test + +import android.util.SparseArray +import android.util.SparseBooleanArray +import android.util.SparseIntArray +import android.util.SparseLongArray +import com.mysugr.android.forEach +import com.mysugr.logbook.BuildConfig +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricGradleTestRunner +import org.robolectric.annotation.Config + + +@RunWith(RobolectricGradleTestRunner::class) +@Config(constants = BuildConfig::class) +public class SparseArraysTest { + + @Test + fun testGenericForEachRandomNumbers() { + val sa = SparseArray() + + sa.put(2, 2.toString()) + sa.put(8, 8.toString()) + sa.put(5, 5.toString()) + sa.put(10, 10.toString()) + sa.put(7, 7.toString()) + sa.put(4, 4.toString()) + sa.put(9, 9.toString()) + sa.put(1, 1.toString()) + sa.put(3, 3.toString()) + sa.put(6, 6.toString()) + + var invokeCount = 0 + sa.forEach { k, v -> + invokeCount++ + Assert.assertEquals(k.toString(), v) + } + + Assert.assertEquals(invokeCount, sa.size()) + } + + @Test + fun testGenericEmptyArray() { + val sa = SparseArray() + sa.forEach { k, v -> throw IllegalStateException("should not be called on an empty array") } + } + + @Test + fun testBooleanArrayForEach() { + val sa = SparseBooleanArray() + + for (i in 1..101) { + sa.put(i, i % 2 == 0) + } + + var invokeCount = 0 + sa.forEach { k, v -> + invokeCount++ + Assert.assertEquals(k % 2 == 0, v ) + } + + Assert.assertEquals(invokeCount, sa.size()) + } + + @Test + fun testBooleanEmptyArray() { + val sa = SparseBooleanArray() + sa.forEach { k, v -> throw IllegalStateException("should not be called on an empty array") } + } + + @Test + fun testIntArrayForEach() { + val sa = SparseIntArray() + + for (i in 1..101) { + sa.put(i, i * 10) + } + + var invokeCount = 0 + sa.forEach { k, v -> + invokeCount++ + Assert.assertEquals(k * 10, v ) + } + + Assert.assertEquals(invokeCount, sa.size()) + } + + @Test + fun testIntEmptyArray() { + val sa = SparseIntArray() + sa.forEach { k, v -> throw IllegalStateException("should not be called on an empty array") } + } +} \ No newline at end of file diff --git a/anko/library/static/common/src/collections/SparseArrays.kt b/anko/library/static/common/src/collections/SparseArrays.kt new file mode 100644 index 00000000..8a77d2f7 --- /dev/null +++ b/anko/library/static/common/src/collections/SparseArrays.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package collections + + +import android.util.SparseArray +import android.util.SparseBooleanArray +import android.util.SparseIntArray +import java.util.* + + +/** + * Iterate the receiver [SparseArray] + * @action an action to invoke on each key value pair + * @throws [ConcurrentModificationException] if modified while iterating + */ +inline fun SparseArray.forEach(action: (Int, E) -> Unit) { + val size = this.size() + for (i in 0..size - 1) { + if (size != this.size()) throw ConcurrentModificationException() + action(this.keyAt(i), this.valueAt(i)) + } +} + +/** + * Iterate the receiver [SparseBooleanArray] + * @action an action to invoke on each key value pair + * @throws [ConcurrentModificationException] if modified while iterating + */ +inline fun SparseBooleanArray.forEach(action: (Int, Boolean) -> Unit) { + val size = this.size() + for (i in 0..size - 1) { + if (size != this.size()) throw ConcurrentModificationException() + action(this.keyAt(i), this.valueAt(i)) + } +} + +/** + * Iterate the receiver [SparseIntArray] + * @action an action to invoke on each key value pair + * @throws [ConcurrentModificationException] if modified while iterating + */ +inline fun SparseIntArray.forEach(action: (Int, Int) -> Unit) { + val size = this.size() + for (i in 0..size - 1) { + if (size != this.size()) throw ConcurrentModificationException() + action(this.keyAt(i), this.valueAt(i)) + } +} + +