Remove stdlib tests
This commit is contained in:
committed by
Pavel Punegov
parent
f41b2a7271
commit
2d5a2c8094
@@ -1,184 +0,0 @@
|
||||
package test.comparisons
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.comparisons.*
|
||||
|
||||
data class Item(val name: String, val rating: Int) : Comparable<Item> {
|
||||
public override fun compareTo(other: Item): Int {
|
||||
return compareValuesBy(this, other, { it.rating }, { it.name })
|
||||
}
|
||||
}
|
||||
|
||||
val STRING_CASE_INSENSITIVE_ORDER: Comparator<String> = compareBy { it: String -> it.toUpperCase() }.thenBy { it.toLowerCase() }.thenBy { it }
|
||||
|
||||
class OrderingTest {
|
||||
val v1 = Item("wine", 9)
|
||||
val v2 = Item("beer", 10)
|
||||
val v3 = Item("apple", 20)
|
||||
|
||||
@Test
|
||||
fun compareByCompareTo() {
|
||||
val diff = v1.compareTo(v2)
|
||||
assertTrue(diff < 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compareByNameFirst() {
|
||||
val diff = compareValuesBy(v1, v2, { it.name }, { it.rating })
|
||||
assertTrue(diff > 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compareByRatingFirst() {
|
||||
val diff = compareValuesBy(v1, v2, { it.rating }, { it.name })
|
||||
assertTrue(diff < 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compareSameObjectsByRatingFirst() {
|
||||
val diff = compareValuesBy(v1, v1, { it.rating }, { it.name })
|
||||
assertTrue(diff == 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compareNullables() {
|
||||
val v1: Item? = this.v1
|
||||
val v2: Item? = null
|
||||
val diff = compareValuesBy(v1, v2) { it?.rating }
|
||||
assertTrue(diff > 0)
|
||||
val diff2 = nullsLast(compareBy<Item> { it.rating }.thenBy { it.name }).compare(v1, v2)
|
||||
assertTrue(diff2 < 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sortComparatorThenComparator() {
|
||||
val comparator = Comparator<Item> { a, b -> a.name.compareTo(b.name) }.thenComparator { a, b -> a.rating.compareTo(b.rating) }
|
||||
|
||||
val diff = comparator.compare(v1, v2)
|
||||
assertTrue(diff > 0)
|
||||
val items = arrayListOf(v1, v2).sortedWith(comparator)
|
||||
assertEquals(v2, items[0])
|
||||
assertEquals(v1, items[1])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun combineComparators() {
|
||||
val byName = compareBy<Item> { it.name }
|
||||
val byRating = compareBy<Item> { it.rating }
|
||||
val v3 = Item(v1.name, v1.rating + 1)
|
||||
val v4 = Item(v2.name + "_", v2.rating)
|
||||
assertTrue( (byName then byRating).compare(v1, v2) > 0 )
|
||||
assertTrue( (byName then byRating).compare(v1, v3) < 0 )
|
||||
assertTrue( (byName thenDescending byRating).compare(v1, v3) > 0 )
|
||||
|
||||
assertTrue( (byRating then byName).compare(v1, v2) < 0 )
|
||||
assertTrue( (byRating then byName).compare(v4, v2) > 0 )
|
||||
assertTrue( (byRating thenDescending byName).compare(v4, v2) < 0 )
|
||||
}
|
||||
|
||||
@Test
|
||||
fun reversedComparator() {
|
||||
val comparator = compareBy<Item> { it.name }
|
||||
val reversed = comparator.reversed()
|
||||
assertEquals(comparator.compare(v2, v1), reversed.compare(v1, v2))
|
||||
assertEquals(comparator, reversed.reversed())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun naturalOrderComparator() {
|
||||
val v1 = "a"
|
||||
val v2 = "beta"
|
||||
|
||||
assertTrue(naturalOrder<String>().compare(v1, v2) < 0)
|
||||
assertTrue(reverseOrder<String>().compare(v1, v2) > 0)
|
||||
assertTrue(reverseOrder<Int>() === naturalOrder<Int>().reversed())
|
||||
assertTrue(naturalOrder<Int>() === reverseOrder<Int>().reversed())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sortByThenBy() {
|
||||
val comparator = compareBy<Item> { it.rating }.thenBy { it.name }
|
||||
|
||||
val diff = comparator.compare(v1, v2)
|
||||
assertTrue(diff < 0)
|
||||
val items = arrayListOf(v1, v2).sortedWith(comparator)
|
||||
assertEquals(v1, items[0])
|
||||
assertEquals(v2, items[1])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sortByThenByDescending() {
|
||||
val comparator = compareBy<Item> { it.rating }.thenByDescending { it.name }
|
||||
|
||||
val diff = comparator.compare(v1, v2)
|
||||
assertTrue(diff < 0)
|
||||
val items = arrayListOf(v1, v2).sortedWith(comparator)
|
||||
assertEquals(v1, items[0])
|
||||
assertEquals(v2, items[1])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sortUsingFunctionalComparator() {
|
||||
val comparator = compareBy<Item>({ it.name }, { it.rating })
|
||||
val diff = comparator.compare(v1, v2)
|
||||
assertTrue(diff > 0)
|
||||
val items = arrayListOf(v1, v2).sortedWith(comparator)
|
||||
assertEquals(v2, items[0])
|
||||
assertEquals(v1, items[1])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sortUsingCustomComparator() {
|
||||
val comparator = object : Comparator<Item> {
|
||||
override fun compare(o1: Item, o2: Item): Int {
|
||||
return compareValuesBy(o1, o2, { it.name }, { it.rating })
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return this == other
|
||||
}
|
||||
}
|
||||
val diff = comparator.compare(v1, v2)
|
||||
assertTrue(diff > 0)
|
||||
val items = arrayListOf(v1, v2).sortedWith(comparator)
|
||||
assertEquals(v2, items[0])
|
||||
assertEquals(v1, items[1])
|
||||
}
|
||||
|
||||
@Test fun maxOf() {
|
||||
assertEquals(Int.MAX_VALUE, maxOf(Int.MAX_VALUE, Int.MIN_VALUE))
|
||||
assertEquals(Int.MAX_VALUE, maxOf(Int.MAX_VALUE, Int.MIN_VALUE, 0))
|
||||
|
||||
assertEquals(Long.MAX_VALUE, maxOf(Long.MAX_VALUE, Long.MIN_VALUE))
|
||||
assertEquals(Long.MAX_VALUE, maxOf(Long.MAX_VALUE, Long.MIN_VALUE, 0))
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, maxOf(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY))
|
||||
assertEquals(Double.POSITIVE_INFINITY, maxOf(Double.POSITIVE_INFINITY, Double.MAX_VALUE, Double.MIN_VALUE))
|
||||
}
|
||||
|
||||
@Test fun maxOfWith() {
|
||||
assertEquals(v1, maxOf(v1, v2, compareBy { it.name }))
|
||||
assertEquals(v1, maxOf(v3, v2, v1, compareBy { it.name }))
|
||||
assertEquals(v2, maxOf(v1, v2, compareBy { it.rating }))
|
||||
assertEquals(v3, maxOf(v1, v2, v3, compareBy { it.rating }))
|
||||
}
|
||||
|
||||
@Test fun minOf() {
|
||||
assertEquals(Int.MIN_VALUE, minOf(Int.MAX_VALUE, Int.MIN_VALUE))
|
||||
assertEquals(Int.MIN_VALUE, minOf(Int.MAX_VALUE, Int.MIN_VALUE, 0))
|
||||
|
||||
assertEquals(Long.MIN_VALUE, minOf(Long.MAX_VALUE, Long.MIN_VALUE))
|
||||
assertEquals(Long.MIN_VALUE, minOf(Long.MAX_VALUE, Long.MIN_VALUE, 0))
|
||||
|
||||
assertEquals(Double.NEGATIVE_INFINITY, minOf(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY))
|
||||
assertEquals(Double.MIN_VALUE, minOf(Double.POSITIVE_INFINITY, Double.MAX_VALUE, Double.MIN_VALUE))
|
||||
}
|
||||
|
||||
@Test fun minOfWith() {
|
||||
assertEquals(v2, minOf(v1, v2, compareBy { it.name }))
|
||||
assertEquals(v3, minOf(v3, v2, v1, compareBy { it.name }))
|
||||
assertEquals(v1, minOf(v1, v2, compareBy { it.rating }))
|
||||
assertEquals(v1, minOf(v1, v2, v3, compareBy { it.rating }))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package test.tuples
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class PairTest {
|
||||
val p = Pair(1, "a")
|
||||
|
||||
@Test fun pairFirstAndSecond() {
|
||||
assertEquals(1, p.first)
|
||||
assertEquals("a", p.second)
|
||||
}
|
||||
|
||||
@Test fun pairMultiAssignment() {
|
||||
val (a, b) = p
|
||||
assertEquals(1, a)
|
||||
assertEquals("a", b)
|
||||
}
|
||||
|
||||
@Test fun pairToString() {
|
||||
assertEquals("(1, a)", p.toString())
|
||||
}
|
||||
|
||||
@Test fun pairEquals() {
|
||||
assertEquals(Pair(1, "a"), p)
|
||||
assertNotEquals(Pair(2, "a"), p)
|
||||
assertNotEquals(Pair(1, "b"), p)
|
||||
assertTrue(!p.equals(null))
|
||||
assertNotEquals("", (p as Any))
|
||||
}
|
||||
|
||||
@Test fun pairHashCode() {
|
||||
assertEquals(Pair(1, "a").hashCode(), p.hashCode())
|
||||
assertNotEquals(Pair(2, "a").hashCode(), p.hashCode())
|
||||
assertNotEquals(0, Pair(null, "b").hashCode())
|
||||
assertNotEquals(0, Pair("b", null).hashCode())
|
||||
assertEquals(0, Pair(null, null).hashCode())
|
||||
}
|
||||
|
||||
@Test fun pairHashSet() {
|
||||
val s = hashSetOf(Pair(1, "a"), Pair(1, "b"), Pair(1, "a"))
|
||||
assertEquals(2, s.size)
|
||||
assertTrue(s.contains(p))
|
||||
}
|
||||
|
||||
@Test fun pairToList() {
|
||||
assertEquals(listOf(1, 2), (1 to 2).toList())
|
||||
assertEquals(listOf(1, null), (1 to null).toList())
|
||||
assertEquals(listOf(1, "2"), (1 to "2").toList())
|
||||
}
|
||||
}
|
||||
|
||||
class TripleTest {
|
||||
val t = Triple(1, "a", 0.07)
|
||||
|
||||
@Test fun tripleFirstAndSecond() {
|
||||
assertEquals(1, t.first)
|
||||
assertEquals("a", t.second)
|
||||
assertEquals(0.07, t.third)
|
||||
}
|
||||
|
||||
@Test fun tripleMultiAssignment() {
|
||||
val (a, b, c) = t
|
||||
assertEquals(1, a)
|
||||
assertEquals("a", b)
|
||||
assertEquals(0.07, c)
|
||||
}
|
||||
|
||||
@Test fun tripleToString() {
|
||||
assertEquals("(1, a, 0.07)", t.toString())
|
||||
}
|
||||
|
||||
@Test fun tripleEquals() {
|
||||
assertEquals(Triple(1, "a", 0.07), t)
|
||||
assertNotEquals(Triple(2, "a", 0.07), t)
|
||||
assertNotEquals(Triple(1, "b", 0.07), t)
|
||||
assertNotEquals(Triple(1, "a", 0.1), t)
|
||||
assertTrue(!t.equals(null))
|
||||
assertNotEquals("", (t as Any))
|
||||
}
|
||||
|
||||
@Test fun tripleHashCode() {
|
||||
assertEquals(Triple(1, "a", 0.07).hashCode(), t.hashCode())
|
||||
assertNotEquals(Triple(2, "a", 0.07).hashCode(), t.hashCode())
|
||||
assertNotEquals(0, Triple(null, "b", 0.07).hashCode())
|
||||
assertNotEquals(0, Triple("b", null, 0.07).hashCode())
|
||||
assertNotEquals(0, Triple("b", 1, null).hashCode())
|
||||
assertEquals(0, Triple(null, null, null).hashCode())
|
||||
}
|
||||
|
||||
@Test fun tripleHashSet() {
|
||||
val s = hashSetOf(Triple(1, "a", 0.07), Triple(1, "b", 0.07), Triple(1, "a", 0.07))
|
||||
assertEquals(2, s.size)
|
||||
assertTrue(s.contains(t))
|
||||
}
|
||||
|
||||
@Test fun tripleToList() {
|
||||
assertEquals(listOf(1, 2, 3), (Triple(1, 2, 3)).toList())
|
||||
assertEquals(listOf(1, null, 3), (Triple(1, null, 3)).toList())
|
||||
assertEquals(listOf(1, 2, "3"), (Triple(1, 2, "3")).toList())
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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 test.collections.behaviors
|
||||
|
||||
import test.collections.CompareContext
|
||||
|
||||
public fun <T> CompareContext<List<T>>.listBehavior() {
|
||||
equalityBehavior()
|
||||
collectionBehavior()
|
||||
compareProperty( { listIterator() }, { listIteratorBehavior() })
|
||||
compareProperty( { listIterator(0) }, { listIteratorBehavior() })
|
||||
|
||||
propertyFails { listIterator(-1) }
|
||||
propertyFails { listIterator(size + 1) }
|
||||
|
||||
for (index in expected.indices)
|
||||
propertyEquals { this[index] }
|
||||
|
||||
propertyFails { this[size] }
|
||||
|
||||
propertyEquals { indexOf(elementAtOrNull(0)) }
|
||||
propertyEquals { lastIndexOf(elementAtOrNull(0)) }
|
||||
|
||||
propertyFails { subList(0, size + 1)}
|
||||
propertyFails { subList(-1, 0)}
|
||||
propertyEquals { subList(0, size) }
|
||||
}
|
||||
|
||||
public fun <T> CompareContext<ListIterator<T>>.listIteratorBehavior() {
|
||||
listIteratorProperties()
|
||||
|
||||
while (expected.hasNext()) {
|
||||
propertyEquals { next() }
|
||||
listIteratorProperties()
|
||||
}
|
||||
propertyFails { next() }
|
||||
|
||||
while (expected.hasPrevious()) {
|
||||
propertyEquals { previous() }
|
||||
listIteratorProperties()
|
||||
}
|
||||
propertyFails { previous() }
|
||||
}
|
||||
|
||||
public fun CompareContext<ListIterator<*>>.listIteratorProperties() {
|
||||
propertyEquals { hasNext() }
|
||||
propertyEquals { hasPrevious() }
|
||||
propertyEquals { nextIndex() }
|
||||
propertyEquals { previousIndex() }
|
||||
}
|
||||
|
||||
public fun <T> CompareContext<Iterator<T>>.iteratorBehavior() {
|
||||
propertyEquals { hasNext() }
|
||||
|
||||
while (expected.hasNext()) {
|
||||
propertyEquals { next() }
|
||||
propertyEquals { hasNext() }
|
||||
}
|
||||
propertyFails { next() }
|
||||
}
|
||||
|
||||
public fun <T> CompareContext<Set<T>>.setBehavior(objectName: String = "") {
|
||||
equalityBehavior(objectName)
|
||||
collectionBehavior(objectName)
|
||||
compareProperty({ iterator() }, { iteratorBehavior() })
|
||||
}
|
||||
|
||||
public fun <K, V> CompareContext<Map<K, V>>.mapBehavior() {
|
||||
equalityBehavior()
|
||||
propertyEquals { size }
|
||||
propertyEquals { isEmpty() }
|
||||
|
||||
(object {}).let { propertyEquals { containsKey(it as Any?) } }
|
||||
|
||||
if (expected.isEmpty().not())
|
||||
propertyEquals { contains(keys.first()) }
|
||||
|
||||
propertyEquals { containsKey(keys.firstOrNull()) }
|
||||
propertyEquals { containsValue(values.firstOrNull()) }
|
||||
propertyEquals { get(null as Any?) }
|
||||
|
||||
compareProperty( { keys }, { setBehavior("keySet") } )
|
||||
compareProperty( { entries }, { setBehavior("entrySet") } )
|
||||
compareProperty( { values }, { collectionBehavior("values") })
|
||||
}
|
||||
|
||||
public fun <T> CompareContext<T>.equalityBehavior(objectName: String = "") {
|
||||
val prefix = objectName + if (objectName.isNotEmpty()) "." else ""
|
||||
equals(objectName)
|
||||
propertyEquals(prefix + "hashCode") { hashCode() }
|
||||
propertyEquals(prefix + "toString") { toString() }
|
||||
}
|
||||
|
||||
|
||||
public fun <T> CompareContext<Collection<T>>.collectionBehavior(objectName: String = "") {
|
||||
val prefix = objectName + if (objectName.isNotEmpty()) "." else ""
|
||||
propertyEquals (prefix + "size") { size }
|
||||
propertyEquals (prefix + "isEmpty") { isEmpty() }
|
||||
|
||||
(object {}).let { propertyEquals { contains(it as Any?) } }
|
||||
propertyEquals { contains(firstOrNull()) }
|
||||
propertyEquals { containsAll(this) }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,941 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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 test.collections
|
||||
|
||||
import kotlin.test.*
|
||||
import test.collections.behaviors.*
|
||||
import test.comparisons.STRING_CASE_INSENSITIVE_ORDER
|
||||
import kotlin.comparisons.*
|
||||
|
||||
class CollectionTest {
|
||||
|
||||
@Test fun createListWithInit() {
|
||||
val list = List(3) { index -> "x".repeat(index + 1) }
|
||||
assertEquals(3, list.size)
|
||||
assertEquals(listOf("x", "xx", "xxx"), list)
|
||||
}
|
||||
|
||||
@Test fun joinTo() {
|
||||
val data = listOf("foo", "bar")
|
||||
val buffer = StringBuilder()
|
||||
data.joinTo(buffer, "-", "{", "}")
|
||||
assertEquals("{foo-bar}", buffer.toString())
|
||||
}
|
||||
|
||||
@Test fun joinToString() {
|
||||
val data = listOf("foo", "bar")
|
||||
val text = data.joinToString("-", "<", ">")
|
||||
assertEquals("<foo-bar>", text)
|
||||
|
||||
val mixed = listOf('a', "b", StringBuilder("c"), null, "d", 'e', 'f')
|
||||
val text2 = mixed.joinToString(limit = 4, truncated = "*")
|
||||
assertEquals("a, b, c, null, *", text2)
|
||||
}
|
||||
|
||||
@Test fun filterNotNull() {
|
||||
val data = listOf(null, "foo", null, "bar")
|
||||
val foo = data.filterNotNull()
|
||||
|
||||
assertEquals(2, foo.size)
|
||||
assertEquals(listOf("foo", "bar"), foo)
|
||||
|
||||
assertTrue {
|
||||
foo is List<String>
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Test fun mapNotNull() {
|
||||
val data = listOf(null, "foo", null, "bar")
|
||||
val foo = data.mapNotNull { it.length() }
|
||||
assertEquals(2, foo.size())
|
||||
assertEquals(listOf(3, 3), foo)
|
||||
|
||||
assertTrue {
|
||||
foo is List<Int>
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@Test fun listOfNotNull() {
|
||||
val l1: List<Int> = listOfNotNull(null)
|
||||
assertTrue(l1.isEmpty())
|
||||
|
||||
val s: String? = "value"
|
||||
val l2: List<String> = listOfNotNull(s)
|
||||
assertEquals(s, l2.single())
|
||||
|
||||
val l3: List<String> = listOfNotNull("value1", null, "value2")
|
||||
assertEquals(listOf("value1", "value2"), l3)
|
||||
}
|
||||
|
||||
@Test fun filterIntoSet() {
|
||||
val data = listOf("foo", "bar")
|
||||
val foo = data.filterTo(hashSetOf<String>()) { it.startsWith("f") }
|
||||
|
||||
assertTrue {
|
||||
foo.all { it.startsWith("f") }
|
||||
}
|
||||
assertEquals(1, foo.size)
|
||||
assertEquals(hashSetOf("foo"), foo)
|
||||
|
||||
assertTrue {
|
||||
foo is HashSet<String>
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun filterIsInstanceList() {
|
||||
val values: List<Any> = listOf(1, 2, 3.0, "abc", "cde")
|
||||
|
||||
val numberValues: List<Number> = values.filterIsInstance<Number>()
|
||||
assertEquals(listOf(1, 2, 3.0), numberValues)
|
||||
|
||||
// doesn't distinguish double from int in JS
|
||||
// val doubleValues: List<Double> = values.filterIsInstance<Double>()
|
||||
// assertEquals(listOf(3.0), doubleValues)
|
||||
|
||||
val stringValues: List<String> = values.filterIsInstance<String>()
|
||||
assertEquals(listOf("abc", "cde"), stringValues)
|
||||
|
||||
// is Any doesn't work in JS, see KT-7665
|
||||
// val anyValues: List<Any> = values.filterIsInstance<Any>()
|
||||
// assertEquals(values.toList(), anyValues)
|
||||
|
||||
val charValues: List<Char> = values.filterIsInstance<Char>()
|
||||
assertEquals(0, charValues.size)
|
||||
}
|
||||
|
||||
@Test fun filterIsInstanceArray() {
|
||||
val src: Array<Any> = arrayOf(1, 2, 3.0, "abc", "cde")
|
||||
|
||||
val numberValues: List<Number> = src.filterIsInstance<Number>()
|
||||
assertEquals(listOf(1, 2, 3.0), numberValues)
|
||||
|
||||
// doesn't distinguish double from int in JS
|
||||
// val doubleValues: List<Double> = src.filterIsInstance<Double>()
|
||||
// assertEquals(listOf(3.0), doubleValues)
|
||||
|
||||
val stringValues: List<String> = src.filterIsInstance<String>()
|
||||
assertEquals(listOf("abc", "cde"), stringValues)
|
||||
|
||||
// is Any doesn't work in JS, see KT-7665
|
||||
// val anyValues: List<Any> = src.filterIsInstance<Any>()
|
||||
// assertEquals(src.toList(), anyValues)
|
||||
|
||||
val charValues: List<Char> = src.filterIsInstance<Char>()
|
||||
assertEquals(0, charValues.size)
|
||||
}
|
||||
|
||||
@Test fun foldIndexed() {
|
||||
expect(42) {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.foldIndexed(0) { index, a, b -> index * (a + b) }
|
||||
}
|
||||
|
||||
expect(0) {
|
||||
val numbers = arrayListOf<Int>()
|
||||
numbers.foldIndexed(0) { index, a, b -> index * (a + b) }
|
||||
}
|
||||
|
||||
expect("11234") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.map { it.toString() }.foldIndexed("") { index, a, b -> if (index == 0) a + b + b else a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldIndexedWithDifferentTypes() {
|
||||
expect(10) {
|
||||
val numbers = listOf("a", "ab", "abc")
|
||||
numbers.foldIndexed(1) { index, a, b -> a + b.length + index }
|
||||
}
|
||||
|
||||
expect("11223344") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.foldIndexed("") { index, a, b -> a + b + (index + 1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldIndexedWithNonCommutativeOperation() {
|
||||
expect(4) {
|
||||
val numbers = listOf(1, 2, 3)
|
||||
numbers.foldIndexed(7) { index, a, b -> index + a - b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldRightIndexed() {
|
||||
expect("12343210") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.map { it.toString() }.foldRightIndexed("") { index, a, b -> a + b + index }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldRightIndexedWithDifferentTypes() {
|
||||
expect("12343210") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.foldRightIndexed("") { index, a, b -> "" + a + b + index }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldRightIndexedWithNonCommutativeOperation() {
|
||||
expect(-4) {
|
||||
val numbers = listOf(1, 2, 3)
|
||||
numbers.foldRightIndexed(7) { index, a, b -> index + a - b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun fold() {
|
||||
// lets calculate the sum of some numbers
|
||||
expect(10) {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.fold(0) { a, b -> a + b }
|
||||
}
|
||||
|
||||
expect(0) {
|
||||
val numbers = arrayListOf<Int>()
|
||||
numbers.fold(0) { a, b -> a + b }
|
||||
}
|
||||
|
||||
// lets concatenate some strings
|
||||
expect("1234") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.map { it.toString() }.fold("") { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldWithDifferentTypes() {
|
||||
expect(7) {
|
||||
val numbers = listOf("a", "ab", "abc")
|
||||
numbers.fold(1) { a, b -> a + b.length }
|
||||
}
|
||||
|
||||
expect("1234") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.fold("") { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldWithNonCommutativeOperation() {
|
||||
expect(1) {
|
||||
val numbers = listOf(1, 2, 3)
|
||||
numbers.fold(7) { a, b -> a - b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldRight() {
|
||||
expect("1234") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.map { it.toString() }.foldRight("") { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldRightWithDifferentTypes() {
|
||||
expect("1234") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.foldRight("") { a, b -> "" + a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun foldRightWithNonCommutativeOperation() {
|
||||
expect(-5) {
|
||||
val numbers = listOf(1, 2, 3)
|
||||
numbers.foldRight(7) { a, b -> a - b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun zipTransform() {
|
||||
expect(listOf("ab", "bc", "cd")) {
|
||||
listOf("a", "b", "c").zip(listOf("b", "c", "d")) { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun zip() {
|
||||
expect(listOf("a" to "b", "b" to "c", "c" to "d")) {
|
||||
listOf("a", "b", "c").zip(listOf("b", "c", "d"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun partition() {
|
||||
val data = listOf("foo", "bar", "something", "xyz")
|
||||
val pair = data.partition { it.length == 3 }
|
||||
|
||||
assertEquals(listOf("foo", "bar", "xyz"), pair.first, "pair.first")
|
||||
assertEquals(listOf("something"), pair.second, "pair.second")
|
||||
}
|
||||
|
||||
@Test fun reduceIndexed() {
|
||||
expect("123") {
|
||||
val list = listOf("1", "2", "3", "4")
|
||||
list.reduceIndexed { index, a, b -> if (index == 3) a else a + b }
|
||||
}
|
||||
|
||||
expect(5) {
|
||||
listOf(2, 3).reduceIndexed { index, acc: Number, e ->
|
||||
assertEquals(1, index)
|
||||
assertEquals(2, acc)
|
||||
assertEquals(3, e)
|
||||
acc.toInt() + e
|
||||
}
|
||||
}
|
||||
|
||||
assertFailsWith<UnsupportedOperationException> {
|
||||
arrayListOf<Int>().reduceIndexed { index, a, b -> index + a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun reduceRightIndexed() {
|
||||
expect("234") {
|
||||
val list = listOf("1", "2", "3", "4")
|
||||
list.reduceRightIndexed { index, a, b -> if (index == 0) b else a + b }
|
||||
}
|
||||
|
||||
expect(1) {
|
||||
listOf(2, 3).reduceRightIndexed { index, e, acc: Number ->
|
||||
assertEquals(0, index)
|
||||
assertEquals(3, acc)
|
||||
assertEquals(2, e)
|
||||
acc.toInt() - e
|
||||
}
|
||||
}
|
||||
|
||||
assertFailsWith<UnsupportedOperationException> {
|
||||
arrayListOf<Int>().reduceRightIndexed { index, a, b -> index + a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun reduce() {
|
||||
expect("1234") {
|
||||
val list = listOf("1", "2", "3", "4")
|
||||
list.reduce { a, b -> a + b }
|
||||
}
|
||||
|
||||
assertFailsWith<UnsupportedOperationException> {
|
||||
arrayListOf<Int>().reduce { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun reduceRight() {
|
||||
expect("1234") {
|
||||
val list = listOf("1", "2", "3", "4")
|
||||
list.reduceRight { a, b -> a + b }
|
||||
}
|
||||
|
||||
assertFailsWith<UnsupportedOperationException> {
|
||||
arrayListOf<Int>().reduceRight { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun groupBy() {
|
||||
val words = listOf("a", "abc", "ab", "def", "abcd")
|
||||
val byLength = words.groupBy { it.length }
|
||||
assertEquals(4, byLength.size)
|
||||
|
||||
// verify that order of keys is preserved
|
||||
assertEquals(listOf(
|
||||
1 to listOf("a"),
|
||||
3 to listOf("abc", "def"),
|
||||
2 to listOf("ab"),
|
||||
4 to listOf("abcd")
|
||||
), byLength.toList())
|
||||
|
||||
val l3 = byLength[3].orEmpty()
|
||||
assertEquals(listOf("abc", "def"), l3)
|
||||
}
|
||||
|
||||
@Test fun groupByKeysAndValues() {
|
||||
val nameToTeam = listOf("Alice" to "Marketing", "Bob" to "Sales", "Carol" to "Marketing")
|
||||
val namesByTeam = nameToTeam.groupBy({ it.second }, { it.first })
|
||||
assertEquals(
|
||||
listOf(
|
||||
"Marketing" to listOf("Alice", "Carol"),
|
||||
"Sales" to listOf("Bob")
|
||||
),
|
||||
namesByTeam.toList())
|
||||
|
||||
|
||||
val mutableNamesByTeam = nameToTeam.groupByTo(HashMap(), { it.second }, { it.first })
|
||||
assertEquals(namesByTeam, mutableNamesByTeam)
|
||||
}
|
||||
|
||||
@Test fun plusRanges() {
|
||||
val range1 = 1..3
|
||||
val range2 = 4..7
|
||||
val combined = range1 + range2
|
||||
assertEquals((1..7).toList(), combined)
|
||||
}
|
||||
|
||||
@Test fun mapRanges() {
|
||||
val range = (1..3).map { it * 2 }
|
||||
assertEquals(listOf(2, 4, 6), range)
|
||||
}
|
||||
|
||||
fun testPlus(doPlus: (List<String>) -> List<String>) {
|
||||
val list = listOf("foo", "bar")
|
||||
val list2: List<String> = doPlus(list)
|
||||
assertEquals(listOf("foo", "bar"), list)
|
||||
assertEquals(listOf("foo", "bar", "cheese", "wine"), list2)
|
||||
}
|
||||
|
||||
@Test fun plusElement() = testPlus { it + "cheese" + "wine" }
|
||||
@Test fun plusCollection() = testPlus { it + listOf("cheese", "wine") }
|
||||
@Test fun plusArray() = testPlus { it + arrayOf("cheese", "wine") }
|
||||
@Test fun plusSequence() = testPlus { it + sequenceOf("cheese", "wine") }
|
||||
|
||||
@Test fun plusCollectionBug() {
|
||||
val list = listOf("foo", "bar") + listOf("cheese", "wine")
|
||||
assertEquals(listOf("foo", "bar", "cheese", "wine"), list)
|
||||
}
|
||||
|
||||
@Test fun plusCollectionInference() {
|
||||
val listOfLists = listOf(listOf("s"))
|
||||
val elementList = listOf("a")
|
||||
val result: List<List<String>> = listOfLists.plusElement(elementList)
|
||||
assertEquals(listOf(listOf("s"), listOf("a")), result, "should be list + element")
|
||||
|
||||
val listOfAny = listOf<Any>("a") + listOf<Any>("b")
|
||||
assertEquals(listOf("a", "b"), listOfAny, "should be list + list")
|
||||
|
||||
val listOfAnyAndList = listOf<Any>("a") + listOf<Any>("b") as Any
|
||||
assertEquals(listOf("a", listOf("b")), listOfAnyAndList, "should be list + Any")
|
||||
}
|
||||
|
||||
@Test fun plusAssign() {
|
||||
// lets use a mutable variable of readonly list
|
||||
var l: List<String> = listOf("cheese")
|
||||
val lOriginal = l
|
||||
l += "foo"
|
||||
l += listOf("beer")
|
||||
l += arrayOf("cheese", "wine")
|
||||
l += sequenceOf("bar", "foo")
|
||||
assertEquals(listOf("cheese", "foo", "beer", "cheese", "wine", "bar", "foo"), l)
|
||||
assertTrue(l !== lOriginal)
|
||||
|
||||
val ml = arrayListOf("cheese")
|
||||
ml += "foo"
|
||||
ml += listOf("beer")
|
||||
ml += arrayOf("cheese", "wine")
|
||||
ml += sequenceOf("bar", "foo")
|
||||
assertEquals(l, ml)
|
||||
}
|
||||
|
||||
|
||||
private fun testMinus(expected: List<String>? = null, doMinus: (List<String>) -> List<String>) {
|
||||
val a = listOf("foo", "bar", "bar")
|
||||
val b: List<String> = doMinus(a)
|
||||
val expected_ = expected ?: listOf("foo")
|
||||
assertEquals(expected_, b.toList())
|
||||
}
|
||||
|
||||
@Test fun minusElement() = testMinus(expected = listOf("foo", "bar")) { it - "bar" - "zoo" }
|
||||
@Test fun minusCollection() = testMinus { it - listOf("bar", "zoo") }
|
||||
@Test fun minusArray() = testMinus { it - arrayOf("bar", "zoo") }
|
||||
@Test fun minusSequence() = testMinus { it - sequenceOf("bar", "zoo") }
|
||||
|
||||
@Test fun minusIsEager() {
|
||||
val source = listOf("foo", "bar")
|
||||
val list = arrayListOf<String>()
|
||||
val result = source - list
|
||||
|
||||
list += "foo"
|
||||
assertEquals(source, result)
|
||||
list += "bar"
|
||||
assertEquals(source, result)
|
||||
}
|
||||
|
||||
@Test fun minusAssign() {
|
||||
// lets use a mutable variable of readonly list
|
||||
val data: List<String> = listOf("cheese", "foo", "beer", "cheese", "wine")
|
||||
var l = data
|
||||
l -= "cheese"
|
||||
assertEquals(listOf("foo", "beer", "cheese", "wine"), l)
|
||||
l = data
|
||||
l -= listOf("cheese", "beer")
|
||||
assertEquals(listOf("foo", "wine"), l)
|
||||
l -= arrayOf("wine", "bar")
|
||||
assertEquals(listOf("foo"), l)
|
||||
|
||||
val ml = arrayListOf("cheese", "cheese", "foo", "beer", "cheese", "wine")
|
||||
ml -= "cheese"
|
||||
assertEquals(listOf("cheese", "foo", "beer", "cheese", "wine"), ml)
|
||||
ml -= listOf("cheese", "beer")
|
||||
assertEquals(listOf("foo", "wine"), ml)
|
||||
ml -= arrayOf("wine", "bar")
|
||||
assertEquals(listOf("foo"), ml)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test fun requireNoNulls() {
|
||||
val data = arrayListOf<String?>("foo", "bar")
|
||||
val notNull = data.requireNoNulls()
|
||||
assertEquals(listOf("foo", "bar"), notNull)
|
||||
|
||||
val hasNulls = listOf("foo", null, "bar")
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
// should throw an exception as we have a null
|
||||
hasNulls.requireNoNulls()
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun reverseInPlace() {
|
||||
val data = arrayListOf<String>()
|
||||
data.reverse()
|
||||
assertTrue(data.isEmpty())
|
||||
|
||||
data.add("foo")
|
||||
data.reverse()
|
||||
assertEquals(listOf("foo"), data)
|
||||
|
||||
data.add("bar")
|
||||
data.reverse()
|
||||
assertEquals(listOf("bar", "foo"), data)
|
||||
|
||||
data.add("zoo")
|
||||
data.reverse()
|
||||
assertEquals(listOf("zoo", "foo", "bar"), data)
|
||||
}
|
||||
|
||||
@Test fun reversed() {
|
||||
val data = listOf("foo", "bar")
|
||||
val rev = data.reversed()
|
||||
assertEquals(listOf("bar", "foo"), rev)
|
||||
assertNotEquals(data, rev)
|
||||
}
|
||||
|
||||
|
||||
@Test fun drop() {
|
||||
val coll = listOf("foo", "bar", "abc")
|
||||
assertEquals(listOf("bar", "abc"), coll.drop(1))
|
||||
assertEquals(listOf("abc"), coll.drop(2))
|
||||
}
|
||||
|
||||
@Test fun dropWhile() {
|
||||
val coll = listOf("foo", "bar", "abc")
|
||||
assertEquals(listOf("bar", "abc"), coll.dropWhile { it.startsWith("f") })
|
||||
}
|
||||
|
||||
@Test fun dropLast() {
|
||||
val coll = listOf("foo", "bar", "abc")
|
||||
assertEquals(coll, coll.dropLast(0))
|
||||
assertEquals(emptyList<String>(), coll.dropLast(coll.size))
|
||||
assertEquals(emptyList<String>(), coll.dropLast(coll.size + 1))
|
||||
assertEquals(listOf("foo", "bar"), coll.dropLast(1))
|
||||
assertEquals(listOf("foo"), coll.dropLast(2))
|
||||
|
||||
assertFails { coll.dropLast(-1) }
|
||||
}
|
||||
|
||||
@Test fun dropLastWhile() {
|
||||
val coll = listOf("Foo", "bare", "abc" )
|
||||
assertEquals(coll, coll.dropLastWhile { false })
|
||||
assertEquals(listOf<String>(), coll.dropLastWhile { true })
|
||||
assertEquals(listOf("Foo", "bare"), coll.dropLastWhile { it.length < 4 })
|
||||
assertEquals(listOf("Foo"), coll.dropLastWhile { it.all { it in 'a'..'z' } })
|
||||
}
|
||||
|
||||
@Test fun take() {
|
||||
val coll = listOf("foo", "bar", "abc")
|
||||
assertEquals(emptyList<String>(), coll.take(0))
|
||||
assertEquals(listOf("foo"), coll.take(1))
|
||||
assertEquals(listOf("foo", "bar"), coll.take(2))
|
||||
assertEquals(coll, coll.take(coll.size))
|
||||
assertEquals(coll, coll.take(coll.size + 1))
|
||||
|
||||
assertFails { coll.take(-1) }
|
||||
}
|
||||
|
||||
@Test fun takeWhile() {
|
||||
val coll = listOf("foo", "bar", "abc")
|
||||
assertEquals(emptyList<String>(), coll.takeWhile { false })
|
||||
assertEquals(coll, coll.takeWhile { true })
|
||||
assertEquals(listOf("foo"), coll.takeWhile { it.startsWith("f") })
|
||||
assertEquals(listOf("foo", "bar", "abc"), coll.takeWhile { it.length == 3 })
|
||||
}
|
||||
|
||||
@Test fun takeLast() {
|
||||
val coll = listOf("foo", "bar", "abc")
|
||||
|
||||
assertEquals(emptyList<String>(), coll.takeLast(0))
|
||||
assertEquals(listOf("abc"), coll.takeLast(1))
|
||||
assertEquals(listOf("bar", "abc"), coll.takeLast(2))
|
||||
assertEquals(coll, coll.takeLast(coll.size))
|
||||
assertEquals(coll, coll.takeLast(coll.size + 1))
|
||||
|
||||
assertFails { coll.takeLast(-1) }
|
||||
|
||||
val collWithoutRandomAccess = object : List<String> by coll {}
|
||||
assertEquals(listOf("abc"), collWithoutRandomAccess.takeLast(1))
|
||||
assertEquals(listOf("bar", "abc"), collWithoutRandomAccess.takeLast(2))
|
||||
}
|
||||
|
||||
@Test fun takeLastWhile() {
|
||||
val coll = listOf("foo", "bar", "abc")
|
||||
assertEquals(emptyList<String>(), coll.takeLastWhile { false })
|
||||
assertEquals(coll, coll.takeLastWhile { true })
|
||||
assertEquals(listOf("abc"), coll.takeLastWhile { it.startsWith("a") })
|
||||
assertEquals(listOf("bar", "abc"), coll.takeLastWhile { it[0] < 'c' })
|
||||
}
|
||||
|
||||
@Test fun copyToArray() {
|
||||
val data = listOf("foo", "bar")
|
||||
val arr = data.toTypedArray()
|
||||
println("Got array ${arr}")
|
||||
assertEquals(2, arr.size)
|
||||
}
|
||||
|
||||
@Test fun count() {
|
||||
val data = listOf("foo", "bar")
|
||||
assertEquals(2, data.count())
|
||||
assertEquals(3, hashSetOf(12, 14, 15).count())
|
||||
assertEquals(0, ArrayList<Double>().count())
|
||||
}
|
||||
|
||||
@Test fun first() {
|
||||
val data = listOf("foo", "bar")
|
||||
assertEquals("foo", data.first())
|
||||
assertEquals(15, listOf(15, 19, 20, 25).first())
|
||||
assertEquals('a', listOf('a').first())
|
||||
assertFails { arrayListOf<Int>().first() }
|
||||
}
|
||||
|
||||
@Test fun last() {
|
||||
val data = listOf("foo", "bar")
|
||||
assertEquals("bar", data.last())
|
||||
assertEquals(25, listOf(15, 19, 20, 25).last())
|
||||
assertEquals('a', listOf('a').last())
|
||||
assertFails { arrayListOf<Int>().last() }
|
||||
}
|
||||
|
||||
@Test fun subscript() {
|
||||
val list = arrayListOf("foo", "bar")
|
||||
assertEquals("foo", list[0])
|
||||
assertEquals("bar", list[1])
|
||||
|
||||
// lists throw an exception if out of range
|
||||
assertFails {
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
val outOfBounds = list[2]
|
||||
}
|
||||
|
||||
// lets try update the list
|
||||
list[0] = "new"
|
||||
list[1] = "thing"
|
||||
|
||||
// lists don't allow you to set past the end of the list
|
||||
assertFails {
|
||||
list[2] = "works"
|
||||
}
|
||||
|
||||
list.add("works")
|
||||
assertEquals(listOf("new", "thing", "works"), list)
|
||||
}
|
||||
|
||||
@Test fun indices() {
|
||||
val data = listOf("foo", "bar")
|
||||
val indices = data.indices
|
||||
assertEquals(0, indices.start)
|
||||
assertEquals(1, indices.endInclusive)
|
||||
assertEquals(0..data.size - 1, indices)
|
||||
}
|
||||
|
||||
@Test fun contains() {
|
||||
assertFalse(hashSetOf<Int>().contains(12))
|
||||
assertTrue(listOf(15, 19, 20).contains(15))
|
||||
|
||||
assertTrue(hashSetOf(45, 14, 13).toIterable().contains(14))
|
||||
}
|
||||
|
||||
@Test fun min() {
|
||||
expect(null, { listOf<Int>().min() })
|
||||
expect(1, { listOf(1).min() })
|
||||
expect(2, { listOf(2, 3).min() })
|
||||
expect(2000000000000, { listOf(3000000000000, 2000000000000).min() })
|
||||
expect('a', { listOf('a', 'b').min() })
|
||||
expect("a", { listOf("a", "b").min() })
|
||||
expect(null, { listOf<Int>().asSequence().min() })
|
||||
expect(2, { listOf(2, 3).asSequence().min() })
|
||||
}
|
||||
|
||||
@Test fun max() {
|
||||
expect(null, { listOf<Int>().max() })
|
||||
expect(1, { listOf(1).max() })
|
||||
expect(3, { listOf(2, 3).max() })
|
||||
expect(3000000000000, { listOf(3000000000000, 2000000000000).max() })
|
||||
expect('b', { listOf('a', 'b').max() })
|
||||
expect("b", { listOf("a", "b").max() })
|
||||
expect(null, { listOf<Int>().asSequence().max() })
|
||||
expect(3, { listOf(2, 3).asSequence().max() })
|
||||
}
|
||||
|
||||
@Test fun minWith() {
|
||||
expect(null, { listOf<Int>().minWith(naturalOrder()) })
|
||||
expect(1, { listOf(1).minWith(naturalOrder()) })
|
||||
expect("a", { listOf("a", "B").minWith(STRING_CASE_INSENSITIVE_ORDER) })
|
||||
expect("a", { listOf("a", "B").asSequence().minWith(STRING_CASE_INSENSITIVE_ORDER) })
|
||||
}
|
||||
|
||||
@Test fun maxWith() {
|
||||
expect(null, { listOf<Int>().maxWith(naturalOrder()) })
|
||||
expect(1, { listOf(1).maxWith(naturalOrder()) })
|
||||
expect("B", { listOf("a", "B").maxWith(STRING_CASE_INSENSITIVE_ORDER) })
|
||||
expect("B", { listOf("a", "B").asSequence().maxWith(STRING_CASE_INSENSITIVE_ORDER) })
|
||||
}
|
||||
|
||||
@Test fun minBy() {
|
||||
expect(null, { listOf<Int>().minBy { it } })
|
||||
expect(1, { listOf(1).minBy { it } })
|
||||
expect(3, { listOf(2, 3).minBy { -it } })
|
||||
expect('a', { listOf('a', 'b').minBy { "x$it" } })
|
||||
expect("b", { listOf("b", "abc").minBy { it.length } })
|
||||
expect(null, { listOf<Int>().asSequence().minBy { it } })
|
||||
expect(3, { listOf(2, 3).asSequence().minBy { -it } })
|
||||
}
|
||||
|
||||
@Test fun maxBy() {
|
||||
expect(null, { listOf<Int>().maxBy { it } })
|
||||
expect(1, { listOf(1).maxBy { it } })
|
||||
expect(2, { listOf(2, 3).maxBy { -it } })
|
||||
expect('b', { listOf('a', 'b').maxBy { "x$it" } })
|
||||
expect("abc", { listOf("b", "abc").maxBy { it.length } })
|
||||
expect(null, { listOf<Int>().asSequence().maxBy { it } })
|
||||
expect(2, { listOf(2, 3).asSequence().maxBy { -it } })
|
||||
}
|
||||
|
||||
@Test fun minByEvaluateOnce() {
|
||||
var c = 0
|
||||
expect(1, { listOf(5, 4, 3, 2, 1).minBy { c++; it * it } })
|
||||
assertEquals(5, c)
|
||||
c = 0
|
||||
expect(1, { listOf(5, 4, 3, 2, 1).asSequence().minBy { c++; it * it } })
|
||||
assertEquals(5, c)
|
||||
}
|
||||
|
||||
@Test fun maxByEvaluateOnce() {
|
||||
var c = 0
|
||||
expect(5, { listOf(5, 4, 3, 2, 1).maxBy { c++; it * it } })
|
||||
assertEquals(5, c)
|
||||
c = 0
|
||||
expect(5, { listOf(5, 4, 3, 2, 1).asSequence().maxBy { c++; it * it } })
|
||||
assertEquals(5, c)
|
||||
}
|
||||
|
||||
@Test fun sum() {
|
||||
expect(0) { arrayListOf<Int>().sum() }
|
||||
expect(14) { listOf(2, 3, 9).sum() }
|
||||
expect(3.0) { listOf(1.0, 2.0).sum() }
|
||||
expect(3000000000000) { arrayListOf<Long>(1000000000000, 2000000000000).sum() }
|
||||
expect(3.0.toFloat()) { arrayListOf<Float>(1.0.toFloat(), 2.0.toFloat()).sum() }
|
||||
expect(3.0.toFloat()) { sequenceOf<Float>(1.0.toFloat(), 2.0.toFloat()).sum() }
|
||||
}
|
||||
|
||||
@Test fun average() {
|
||||
assertTrue { arrayListOf<Int>().average().isNaN() }
|
||||
expect(3.8) { listOf(1, 2, 5, 8, 3).average() }
|
||||
expect(2.1) { sequenceOf(1.6, 2.6, 3.6, 0.6).average() }
|
||||
expect(100.0) { arrayListOf<Byte>(100, 100, 100, 100, 100, 100).average() }
|
||||
val n = 100
|
||||
val range = 0..n
|
||||
expect(n.toDouble()/2) { range.average() }
|
||||
}
|
||||
|
||||
@Test fun takeReturnsFirstNElements() {
|
||||
expect(listOf(1, 2, 3, 4, 5)) { (1..10).take(5) }
|
||||
expect(listOf(1, 2, 3, 4, 5)) { (1..10).toList().take(5) }
|
||||
expect(listOf(1, 2)) { (1..10).take(2) }
|
||||
expect(listOf(1, 2)) { (1..10).toList().take(2) }
|
||||
expect(true) { (0L..5L).take(0).none() }
|
||||
expect(true) { listOf(1L).take(0).none() }
|
||||
expect(listOf(1)) { (1..1).take(10) }
|
||||
expect(listOf(1)) { listOf(1).take(10) }
|
||||
}
|
||||
|
||||
@Test fun sortInPlace() {
|
||||
val data = listOf(11, 3, 7)
|
||||
|
||||
val asc = data.toMutableList()
|
||||
asc.sort()
|
||||
assertEquals(listOf(3, 7, 11), asc)
|
||||
|
||||
val desc = data.toMutableList()
|
||||
desc.sortDescending()
|
||||
assertEquals(listOf(11, 7, 3), desc)
|
||||
}
|
||||
|
||||
@Test fun sorted() {
|
||||
val data = listOf(11, 3, 7)
|
||||
assertEquals(listOf(3, 7, 11), data.sorted())
|
||||
assertEquals(listOf(11, 7, 3), data.sortedDescending())
|
||||
}
|
||||
|
||||
@Test fun sortByInPlace() {
|
||||
val data = arrayListOf("aa" to 20, "ab" to 3, "aa" to 3)
|
||||
data.sortBy { it.second }
|
||||
assertEquals(listOf("ab" to 3, "aa" to 3, "aa" to 20), data)
|
||||
|
||||
data.sortBy { it.first }
|
||||
assertEquals(listOf("aa" to 3, "aa" to 20, "ab" to 3), data)
|
||||
|
||||
data.sortByDescending { (it.first + it.second).length }
|
||||
assertEquals(listOf("aa" to 20, "aa" to 3, "ab" to 3), data)
|
||||
}
|
||||
|
||||
@Test fun sortedBy() {
|
||||
assertEquals(listOf("two" to 3, "three" to 20), listOf("three" to 20, "two" to 3).sortedBy { it.second })
|
||||
assertEquals(listOf("three" to 20, "two" to 3), listOf("three" to 20, "two" to 3).sortedBy { it.first })
|
||||
assertEquals(listOf("three", "two"), listOf("two", "three").sortedByDescending { it.length })
|
||||
}
|
||||
|
||||
@Test fun sortedNullableBy() {
|
||||
fun String.nullIfEmpty() = if (isEmpty()) null else this
|
||||
listOf(null, "", "a").let {
|
||||
expect(listOf(null, "", "a")) { it.sortedWith(nullsFirst(compareBy { it })) }
|
||||
expect(listOf("a", "", null)) { it.sortedWith(nullsLast(compareByDescending { it })) }
|
||||
expect(listOf(null, "a", "")) { it.sortedWith(nullsFirst(compareByDescending { it.nullIfEmpty() })) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun sortedByNullable() {
|
||||
fun String.nonEmptyLength() = if (isEmpty()) null else length
|
||||
listOf("", "sort", "abc").let {
|
||||
assertEquals(listOf("", "abc", "sort"), it.sortedBy { it.nonEmptyLength() })
|
||||
assertEquals(listOf("sort", "abc", ""), it.sortedByDescending { it.nonEmptyLength() })
|
||||
assertEquals(listOf("abc", "sort", ""), it.sortedWith(compareBy(nullsLast<Int>()) { it.nonEmptyLength()}))
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun sortedWith() {
|
||||
val comparator = compareBy<String> { it.toUpperCase().reversed() }
|
||||
val data = listOf("cat", "dad", "BAD")
|
||||
|
||||
expect(listOf("BAD", "dad", "cat")) { data.sortedWith(comparator) }
|
||||
expect(listOf("cat", "dad", "BAD")) { data.sortedWith(comparator.reversed()) }
|
||||
expect(listOf("BAD", "dad", "cat")) { data.sortedWith(comparator.reversed().reversed()) }
|
||||
}
|
||||
|
||||
@Test fun decomposeFirst() {
|
||||
val (first) = listOf(1, 2)
|
||||
assertEquals(first, 1)
|
||||
}
|
||||
|
||||
@Test fun decomposeSplit() {
|
||||
val (key, value) = "key = value".split("=").map { it.trim() }
|
||||
assertEquals(key, "key")
|
||||
assertEquals(value, "value")
|
||||
}
|
||||
|
||||
@Test fun decomposeList() {
|
||||
val (a, b, c, d, e) = listOf(1, 2, 3, 4, 5)
|
||||
assertEquals(a, 1)
|
||||
assertEquals(b, 2)
|
||||
assertEquals(c, 3)
|
||||
assertEquals(d, 4)
|
||||
assertEquals(e, 5)
|
||||
}
|
||||
|
||||
@Test fun decomposeArray() {
|
||||
val (a, b, c, d, e) = arrayOf(1, 2, 3, 4, 5)
|
||||
assertEquals(a, 1)
|
||||
assertEquals(b, 2)
|
||||
assertEquals(c, 3)
|
||||
assertEquals(d, 4)
|
||||
assertEquals(e, 5)
|
||||
}
|
||||
|
||||
@Test fun decomposeIntArray() {
|
||||
val (a, b, c, d, e) = intArrayOf(1, 2, 3, 4, 5)
|
||||
assertEquals(a, 1)
|
||||
assertEquals(b, 2)
|
||||
assertEquals(c, 3)
|
||||
assertEquals(d, 4)
|
||||
assertEquals(e, 5)
|
||||
}
|
||||
|
||||
@Test fun unzipList() {
|
||||
val list = listOf(1 to 'a', 2 to 'b', 3 to 'c')
|
||||
val (ints, chars) = list.unzip()
|
||||
assertEquals(listOf(1, 2, 3), ints)
|
||||
assertEquals(listOf('a', 'b', 'c'), chars)
|
||||
}
|
||||
|
||||
@Test fun unzipArray() {
|
||||
val array = arrayOf(1 to 'a', 2 to 'b', 3 to 'c')
|
||||
val (ints, chars) = array.unzip()
|
||||
assertEquals(listOf(1, 2, 3), ints)
|
||||
assertEquals(listOf('a', 'b', 'c'), chars)
|
||||
}
|
||||
|
||||
@Test fun specialLists() {
|
||||
compare(arrayListOf<Int>(), listOf<Int>()) { listBehavior() }
|
||||
compare(arrayListOf<Double>(), emptyList<Double>()) { listBehavior() }
|
||||
compare(arrayListOf("value"), listOf("value")) { listBehavior() }
|
||||
}
|
||||
|
||||
@Test fun specialSets() {
|
||||
compare(linkedSetOf<Int>(), setOf<Int>()) { setBehavior() }
|
||||
compare(hashSetOf<Double>(), emptySet<Double>()) { setBehavior() }
|
||||
compare(listOf("value").toMutableSet(), setOf("value")) { setBehavior() }
|
||||
}
|
||||
|
||||
@Test fun specialMaps() {
|
||||
compare(hashMapOf<String, Int>(), mapOf<String, Int>()) { mapBehavior() }
|
||||
compare(linkedMapOf<Int, String>(), emptyMap<Int, String>()) { mapBehavior() }
|
||||
compare(linkedMapOf(2 to 3), mapOf(2 to 3)) { mapBehavior() }
|
||||
}
|
||||
|
||||
@Test fun toStringTest() {
|
||||
// we need toString() inside pattern because of KT-8666
|
||||
assertEquals("[1, a, null, ${Long.MAX_VALUE.toString()}]", listOf(1, "a", null, Long.MAX_VALUE).toString())
|
||||
}
|
||||
|
||||
@Test fun randomAccess() {
|
||||
assertTrue(arrayListOf(1) is RandomAccess, "ArrayList is RandomAccess")
|
||||
assertTrue(listOf(1, 2) is RandomAccess, "Default read-only list implementation is RandomAccess")
|
||||
assertTrue(listOf(1) is RandomAccess, "Default singleton list is RandomAccess")
|
||||
assertTrue(emptyList<Int>() is RandomAccess, "Empty list is RandomAccess")
|
||||
}
|
||||
|
||||
/*
|
||||
Test relies on Kotlin/JVM toTypedArray() implementation that invokes toArray() after the cast to JDK class
|
||||
@Test fun abstractCollectionToArray() {
|
||||
class TestCollection<out E>(val data: Collection<E>) : AbstractCollection<E>() {
|
||||
val invocations = mutableListOf<String>()
|
||||
override val size get() = data.size
|
||||
override fun iterator() = data.iterator()
|
||||
|
||||
override fun toArray(): Array<Any?> {
|
||||
invocations += "toArray1"
|
||||
return data.toTypedArray()
|
||||
}
|
||||
public override fun <T> toArray(array: Array<T>): Array<T> {
|
||||
invocations += "toArray2"
|
||||
return super.toArray(array)
|
||||
}
|
||||
}
|
||||
val data = listOf("abc", "def")
|
||||
val coll = TestCollection(data)
|
||||
|
||||
val arr1 = coll.toTypedArray()
|
||||
assertEquals(data, arr1.asList())
|
||||
assertTrue("toArray1" in coll.invocations || "toArray2" in coll.invocations)
|
||||
|
||||
val arr2: Array<String> = coll.toArray(Array(coll.size + 1) { "" })
|
||||
assertEquals(data + listOf(null), arr2.asList())
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package test.collections
|
||||
|
||||
import test.*
|
||||
import kotlin.reflect.KProperty1
|
||||
import kotlin.test.*
|
||||
|
||||
public fun <T> compare(expected: T, actual: T, block:CompareContext<T>.() -> Unit) {
|
||||
CompareContext(expected, actual).block()
|
||||
}
|
||||
|
||||
public class CompareContext<out T>(public val expected: T, public val actual: T) {
|
||||
|
||||
public fun equals(message: String = "") {
|
||||
assertEquals(expected, actual, message)
|
||||
}
|
||||
|
||||
public fun <P> propertyEquals(property: KProperty1<in T, P>) {
|
||||
propertyEquals(property.name, property)
|
||||
}
|
||||
|
||||
public fun <P> propertyEquals(message: String = "", getter: T.() -> P) {
|
||||
assertEquals(expected.getter(), actual.getter(), message)
|
||||
}
|
||||
public fun propertyFails(getter: T.() -> Unit) { assertFailEquals({expected.getter()}, {actual.getter()}) }
|
||||
public fun <P> compareProperty(getter: T.() -> P, block: CompareContext<P>.() -> Unit) {
|
||||
compare(expected.getter(), actual.getter(), block)
|
||||
}
|
||||
|
||||
private fun assertFailEquals(expected: () -> Unit, actual: () -> Unit) {
|
||||
val expectedFail = assertFails(expected)
|
||||
val actualFail = assertFails(actual)
|
||||
//assertEquals(expectedFail != null, actualFail != null)
|
||||
assertTypeEquals(expectedFail, actualFail)
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package test.collections
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class GroupingTest {
|
||||
|
||||
@Test fun groupingProducers() {
|
||||
|
||||
fun <T, K> verifyGrouping(grouping: Grouping<T, K>, expectedElements: List<T>, expectedKeys: List<K>) {
|
||||
val elements = grouping.sourceIterator().asSequence().toList()
|
||||
val keys = elements.map { grouping.keyOf(it) } // TODO: replace with grouping::keyOf when supported in JS
|
||||
|
||||
assertEquals(expectedElements, elements)
|
||||
assertEquals(expectedKeys, keys)
|
||||
}
|
||||
|
||||
val elements = listOf("foo", "bar", "value", "x")
|
||||
val keySelector: (String) -> Int = { it.length }
|
||||
val keys = elements.map(keySelector)
|
||||
|
||||
fun verifyGrouping(grouping: Grouping<String, Int>) = verifyGrouping(grouping, elements, keys)
|
||||
|
||||
verifyGrouping(elements.groupingBy { it.length })
|
||||
verifyGrouping(elements.toTypedArray().groupingBy(keySelector))
|
||||
verifyGrouping(elements.asSequence().groupingBy(keySelector))
|
||||
|
||||
val charSeq = "some sequence of chars"
|
||||
verifyGrouping(charSeq.groupingBy { it.toInt() }, charSeq.toList(), charSeq.map { it.toInt() })
|
||||
}
|
||||
|
||||
// aggregate and aggregateTo operations are not tested, but they're used in every other operation
|
||||
|
||||
|
||||
@Test fun foldWithConstantInitialValue() {
|
||||
val elements = listOf("foo", "bar", "flea", "zoo", "biscuit")
|
||||
// only collect strings with even length
|
||||
val result = elements.groupingBy { it.first() }.fold(listOf<String>()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }
|
||||
|
||||
assertEquals(mapOf('f' to listOf("flea"), 'b' to emptyList(), 'z' to emptyList()), result)
|
||||
|
||||
val moreElements = listOf("fire", "zero", "abstract")
|
||||
val result2 = moreElements.groupingBy { it.first() }.foldTo(HashMap(result), listOf()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }
|
||||
|
||||
assertEquals(mapOf('f' to listOf("flea", "fire"), 'b' to emptyList(), 'z' to listOf("zero"), 'a' to listOf("abstract")), result2)
|
||||
}
|
||||
|
||||
data class Collector<out K, V>(val key: K, val values: MutableList<V> = mutableListOf<V>())
|
||||
|
||||
@Test fun foldWithComputedInitialValue() {
|
||||
|
||||
fun <K> Collector<K, String>.accumulateIfEven(e: String) = apply { if (e.length % 2 == 0) values.add(e) }
|
||||
fun <K, V> Collector<K, V>.toPair() = key to values as List<V>
|
||||
|
||||
val elements = listOf("foo", "bar", "flea", "zoo", "biscuit")
|
||||
val result = elements.groupingBy { it.first() }
|
||||
.fold({ k, _ -> Collector<Char, String>(k)}, { _, acc, e -> acc.accumulateIfEven(e) })
|
||||
|
||||
val ordered = result.values.sortedBy { it.key }.map { it.toPair() }
|
||||
assertEquals(listOf('b' to emptyList(), 'f' to listOf("flea"), 'z' to emptyList()), ordered)
|
||||
|
||||
val moreElements = listOf("fire", "zero")
|
||||
val result2 = moreElements.groupingBy { it.first() }
|
||||
.foldTo(HashMap(result),
|
||||
{ k, _ -> error("should not be called for $k") },
|
||||
{ _, acc, e -> acc.accumulateIfEven(e) })
|
||||
|
||||
val ordered2 = result2.values.sortedBy { it.key }.map { it.toPair() }
|
||||
assertEquals(listOf('b' to emptyList(), 'f' to listOf("flea", "fire"), 'z' to listOf("zero")), ordered2)
|
||||
}
|
||||
|
||||
inline fun <T, K : Comparable<K>> maxOfBy(a: T, b: T, keySelector: (T) -> K) = if (keySelector(a) >= keySelector(b)) a else b
|
||||
|
||||
@Test fun reduce() {
|
||||
val elements = listOf("foo", "bar", "flea", "zoo", "biscuit")
|
||||
fun Char.isVowel() = this in "aeiou"
|
||||
fun String.countVowels() = count(Char::isVowel)
|
||||
val maxVowels = elements.groupingBy { it.first() }.reduce { _, a, b -> maxOfBy(a, b, String::countVowels) }
|
||||
|
||||
assertEquals(mapOf('f' to "foo", 'b' to "biscuit", 'z' to "zoo"), maxVowels)
|
||||
|
||||
val elements2 = listOf("bar", "z", "fork")
|
||||
val concats = elements2.groupingBy { it.first() }.reduceTo(HashMap(maxVowels)) { _, acc, e -> acc + e }
|
||||
|
||||
assertEquals(mapOf('f' to "foofork", 'b' to "biscuitbar", 'z' to "zooz"), concats)
|
||||
}
|
||||
|
||||
@Test fun countEach() {
|
||||
val elements = listOf("foo", "bar", "flea", "zoo", "biscuit")
|
||||
val counts = elements.groupingBy { it.first() }.eachCount()
|
||||
|
||||
assertEquals(mapOf('f' to 2, 'b' to 2, 'z' to 1), counts)
|
||||
|
||||
val elements2 = arrayOf("zebra", "baz", "cab")
|
||||
val counts2 = elements2.groupingBy { it.last() }.eachCountTo(HashMap(counts))
|
||||
|
||||
assertEquals(mapOf('f' to 2, 'b' to 3, 'a' to 1, 'z' to 2), counts2)
|
||||
}
|
||||
|
||||
/**
|
||||
@Test fun sumEach() {
|
||||
val values = listOf("k" to 50, "b" to 20, "k" to 1000 )
|
||||
val summary = values.groupingBy { it.first }.eachSumOf { it.second }
|
||||
|
||||
assertEquals(mapOf("k" to 1050, "b" to 20), summary)
|
||||
|
||||
val values2 = listOf("key", "ball", "builder", "alpha")
|
||||
val summary2 = values2.groupingBy { it.first().toString() }.eachSumOfTo(HashMap(summary)) { it.length }
|
||||
|
||||
assertEquals(mapOf("k" to 1053, "b" to 31, "a" to 5), summary2)
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,517 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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 test.collections
|
||||
|
||||
import test.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun <T> iterableOf(vararg items: T): Iterable<T> = Iterable { items.iterator() }
|
||||
fun <T> Iterable<T>.toIterable(): Iterable<T> = Iterable { this.iterator() }
|
||||
|
||||
class IterableTest : OrderedIterableTests<Iterable<String>>({ iterableOf(*it) }, iterableOf<String>())
|
||||
class SetTest : IterableTests<Set<String>>({ setOf(*it) }, setOf())
|
||||
class LinkedSetTest : OrderedIterableTests<LinkedHashSet<String>>({ linkedSetOf(*it) }, linkedSetOf())
|
||||
class ListTest : OrderedIterableTests<List<String>>( { listOf(*it) }, listOf<String>())
|
||||
class ArrayListTest : OrderedIterableTests<ArrayList<String>>({ arrayListOf(*it) }, arrayListOf<String>())
|
||||
|
||||
abstract class OrderedIterableTests<T : Iterable<String>>(createFrom: (Array<out String>) -> T, empty: T) : IterableTests<T>(createFrom, empty) {
|
||||
@Test
|
||||
fun indexOf() {
|
||||
expect(0) { data.indexOf("foo") }
|
||||
expect(-1) { empty.indexOf("foo") }
|
||||
expect(1) { data.indexOf("bar") }
|
||||
expect(-1) { data.indexOf("zap") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun lastIndexOf() {
|
||||
expect(0) { data.lastIndexOf("foo") }
|
||||
expect(-1) { empty.lastIndexOf("foo") }
|
||||
expect(1) { data.lastIndexOf("bar") }
|
||||
expect(-1) { data.lastIndexOf("zap") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun indexOfFirst() {
|
||||
expect(-1) { data.indexOfFirst { it.contains("p") } }
|
||||
expect(0) { data.indexOfFirst { it.startsWith('f') } }
|
||||
expect(-1) { empty.indexOfFirst { it.startsWith('f') } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun indexOfLast() {
|
||||
expect(-1) { data.indexOfLast { it.contains("p") } }
|
||||
expect(1) { data.indexOfLast { it.length == 3 } }
|
||||
expect(-1) { empty.indexOfLast { it.startsWith('f') } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun elementAt() {
|
||||
expect("foo") { data.elementAt(0) }
|
||||
expect("bar") { data.elementAt(1) }
|
||||
assertFails { data.elementAt(2) }
|
||||
assertFails { data.elementAt(-1) }
|
||||
assertFails { empty.elementAt(0) }
|
||||
|
||||
expect("foo") { data.elementAtOrElse(0, {""} )}
|
||||
expect("zoo") { data.elementAtOrElse(-1, { "zoo" })}
|
||||
expect("zoo") { data.elementAtOrElse(2, { "zoo" })}
|
||||
expect("zoo") { empty.elementAtOrElse(0) { "zoo" }}
|
||||
|
||||
expect(null) { empty.elementAtOrNull(0) }
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun first() {
|
||||
expect("foo") { data.first() }
|
||||
assertFails {
|
||||
data.first { it.startsWith("x") }
|
||||
}
|
||||
assertFails {
|
||||
empty.first()
|
||||
}
|
||||
expect("foo") { data.first { it.startsWith("f") } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun firstOrNull() {
|
||||
expect(null) { data.firstOrNull { it.startsWith("x") } }
|
||||
expect(null) { empty.firstOrNull() }
|
||||
|
||||
val f = data.firstOrNull { it.startsWith("f") }
|
||||
assertEquals("foo", f)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun last() {
|
||||
assertEquals("bar", data.last())
|
||||
assertFails {
|
||||
data.last { it.startsWith("x") }
|
||||
}
|
||||
assertFails {
|
||||
empty.last()
|
||||
}
|
||||
expect("foo") { data.last { it.startsWith("f") } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun lastOrNull() {
|
||||
expect(null) { data.lastOrNull { it.startsWith("x") } }
|
||||
expect(null) { empty.lastOrNull() }
|
||||
expect("foo") { data.lastOrNull { it.startsWith("f") } }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun zipWithNext() {
|
||||
val data = createFrom("", "a", "xyz")
|
||||
val lengthDeltas = data.zipWithNext { a: String, b: String -> b.length - a.length }
|
||||
assertEquals(listOf(1, 2), lengthDeltas)
|
||||
|
||||
assertTrue(empty.zipWithNext { a: String, b: String -> a + b }.isEmpty())
|
||||
assertTrue(createFrom("foo").zipWithNext { a: String, b: String -> a + b }.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun zipWithNextPairs() {
|
||||
assertTrue(empty.zipWithNext().isEmpty())
|
||||
assertTrue(createFrom("foo").zipWithNext().isEmpty())
|
||||
assertEquals(listOf("a" to "b"), createFrom("a", "b").zipWithNext())
|
||||
assertEquals(listOf("a" to "b", "b" to "c"), createFrom("a", "b", "c").zipWithNext())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun chunked() {
|
||||
val size = 7
|
||||
val data = createFrom(Array(size) { "$it" })
|
||||
val result = data.chunked(4)
|
||||
assertEquals(listOf(
|
||||
listOf("0", "1", "2", "3"),
|
||||
listOf("4", "5", "6")
|
||||
), result)
|
||||
|
||||
val result2 = data.chunked(3) { it.joinToString("") }
|
||||
assertEquals(listOf("012", "345", "6"), result2)
|
||||
|
||||
data.toList().let { expectedSingleChunk ->
|
||||
assertEquals(expectedSingleChunk, data.chunked(size).single())
|
||||
assertEquals(expectedSingleChunk, data.chunked(size + 3).single())
|
||||
}
|
||||
|
||||
assertTrue(empty.chunked(3).isEmpty())
|
||||
|
||||
for (illegalValue in listOf(Int.MIN_VALUE, -1, 0)) {
|
||||
assertFailsWith<IllegalArgumentException>("size $illegalValue") { data.chunked(illegalValue) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun windowed() {
|
||||
val size = 7
|
||||
val data = createFrom(Array(size) { "$it" })
|
||||
val result = data.windowed(4, 2)
|
||||
assertEquals(listOf(
|
||||
listOf("0", "1", "2", "3"),
|
||||
listOf("2", "3", "4", "5")
|
||||
), result)
|
||||
|
||||
val resultPartial = data.windowed(4, 2, partialWindows = true)
|
||||
assertEquals(listOf(
|
||||
listOf("0", "1", "2", "3"),
|
||||
listOf("2", "3", "4", "5"),
|
||||
listOf("4", "5", "6"),
|
||||
listOf("6")
|
||||
), resultPartial)
|
||||
|
||||
|
||||
val result2 = data.windowed(2, 3) { it.joinToString("") }
|
||||
assertEquals(listOf("01", "34"), result2)
|
||||
|
||||
val result2partial = data.windowed(2, 3, partialWindows = true) { it.joinToString("") }
|
||||
assertEquals(listOf("01", "34", "6"), result2partial)
|
||||
|
||||
assertEquals(data.chunked(2), data.windowed(2, 2, partialWindows = true))
|
||||
|
||||
assertEquals(data.take(2), data.windowed(2, size).single())
|
||||
assertEquals(data.take(3), data.windowed(3, size + 3).single())
|
||||
|
||||
assertEquals(data.toList(), data.windowed(size, 1).single())
|
||||
assertTrue(data.windowed(size + 1, 1).isEmpty())
|
||||
|
||||
val result3partial = data.windowed(size, 1, partialWindows = true)
|
||||
result3partial.forEachIndexed { index, window ->
|
||||
assertEquals(size - index, window.size, "size of window#$index")
|
||||
}
|
||||
|
||||
assertTrue(empty.windowed(3, 2).isEmpty())
|
||||
|
||||
for (illegalValue in listOf(Int.MIN_VALUE, -1, 0)) {
|
||||
assertFailsWith<IllegalArgumentException>("size $illegalValue") { data.windowed(illegalValue, 1) }
|
||||
assertFailsWith<IllegalArgumentException>("step $illegalValue") { data.windowed(1, illegalValue) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
abstract class IterableTests<T : Iterable<String>>(val createFrom: (Array<out String>) -> T, val empty: T) {
|
||||
fun createFrom(vararg items: String): T = createFrom(items)
|
||||
|
||||
val data = createFrom("foo", "bar")
|
||||
|
||||
@Test
|
||||
fun any() {
|
||||
expect(true) { data.any() }
|
||||
expect(false) { empty.any() }
|
||||
expect(true) { data.any { it.startsWith("f") } }
|
||||
expect(false) { data.any { it.startsWith("x") } }
|
||||
expect(false) { empty.any { it.startsWith("x") } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun all() {
|
||||
expect(true) { data.all { it.length == 3 } }
|
||||
expect(false) { data.all { it.startsWith("b") } }
|
||||
expect(true) { empty.all { it.startsWith("b") } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun none() {
|
||||
expect(false) { data.none() }
|
||||
expect(true) { empty.none() }
|
||||
expect(false) { data.none { it.length == 3 } }
|
||||
expect(false) { data.none { it.startsWith("b") } }
|
||||
expect(true) { data.none { it.startsWith("x") } }
|
||||
expect(true) { empty.none { it.startsWith("b") } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun filter() {
|
||||
val foo = data.filter { it.startsWith("f") }
|
||||
expect(true) { foo is List<String> }
|
||||
expect(true) { foo.all { it.startsWith("f") } }
|
||||
expect(1) { foo.size }
|
||||
assertEquals(listOf("foo"), foo)
|
||||
}
|
||||
|
||||
@Test fun filterIndexed() {
|
||||
val result = data.filterIndexed { index, value -> value.first() == ('a' + index) }
|
||||
assertEquals(listOf("bar"), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun drop() {
|
||||
val foo = data.drop(1)
|
||||
expect(true) { foo is List<String> }
|
||||
expect(true) { foo.all { it.startsWith("b") } }
|
||||
expect(1) { foo.size }
|
||||
assertEquals(listOf("bar"), foo)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dropWhile() {
|
||||
val foo = data.dropWhile { it[0] == 'f' }
|
||||
expect(true) { foo is List<String> }
|
||||
expect(true) { foo.all { it.startsWith("b") } }
|
||||
expect(1) { foo.size }
|
||||
assertEquals(listOf("bar"), foo)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun filterNot() {
|
||||
val notFoo = data.filterNot { it.startsWith("f") }
|
||||
expect(true) { notFoo is List<String> }
|
||||
expect(true) { notFoo.none { it.startsWith("f") } }
|
||||
expect(1) { notFoo.size }
|
||||
assertEquals(listOf("bar"), notFoo)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun forEach() {
|
||||
var count = 0
|
||||
data.forEach { count += it.length }
|
||||
assertEquals(6, count)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onEach() {
|
||||
var count = 0
|
||||
val newData = data.onEach { count += it.length }
|
||||
assertEquals(6, count)
|
||||
assertTrue(data === newData)
|
||||
|
||||
// static types test
|
||||
assertStaticTypeIs<ArrayList<Int>>(arrayListOf(1, 2, 3).onEach { })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun contains() {
|
||||
assertTrue(data.contains("foo"))
|
||||
assertTrue("bar" in data)
|
||||
assertTrue("baz" !in data)
|
||||
assertFalse("baz" in empty)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun single() {
|
||||
assertFails { data.single() }
|
||||
assertFails { empty.single() }
|
||||
expect("foo") { data.single { it.startsWith("f") } }
|
||||
expect("bar") { data.single { it.startsWith("b") } }
|
||||
assertFails {
|
||||
data.single { it.length == 3 }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun singleOrNull() {
|
||||
expect(null) { data.singleOrNull() }
|
||||
expect(null) { empty.singleOrNull() }
|
||||
expect("foo") { data.singleOrNull { it.startsWith("f") } }
|
||||
expect("bar") { data.singleOrNull { it.startsWith("b") } }
|
||||
expect(null) {
|
||||
data.singleOrNull { it.length == 3 }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun map() {
|
||||
val lengths = data.map { it.length }
|
||||
assertTrue {
|
||||
lengths.all { it == 3 }
|
||||
}
|
||||
assertEquals(2, lengths.size)
|
||||
assertEquals(listOf(3, 3), lengths)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun flatten() {
|
||||
assertEquals(listOf(0, 1, 2, 3, 0, 1, 2, 3), data.map { 0..it.length }.flatten())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapIndexed() {
|
||||
val shortened = data.mapIndexed { index, value -> value.substring(0..index) }
|
||||
assertEquals(2, shortened.size)
|
||||
assertEquals(listOf("f", "ba"), shortened)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun withIndex() {
|
||||
val indexed = data.withIndex().map { it.value.substring(0..it.index) }
|
||||
assertEquals(2, indexed.size)
|
||||
assertEquals(listOf("f", "ba"), indexed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapNotNull() {
|
||||
assertEquals(listOf('o'), data.mapNotNull { it.firstOrNull { c -> c in "oui" } })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapIndexedNotNull() {
|
||||
assertEquals(listOf('b'), data.mapIndexedNotNull { index, s -> s.getOrNull(index - 1) })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun max() {
|
||||
expect("foo") { data.max() }
|
||||
expect("bar") { data.maxBy { it.last() } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun min() {
|
||||
expect("bar") { data.min() }
|
||||
expect("foo") { data.minBy { it.last() } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun count() {
|
||||
expect(2) { data.count() }
|
||||
expect(0) { empty.count() }
|
||||
|
||||
expect(1) { data.count { it.startsWith("f") } }
|
||||
expect(0) { empty.count { it.startsWith("f") } }
|
||||
|
||||
expect(0) { data.count { it.startsWith("x") } }
|
||||
expect(0) { empty.count { it.startsWith("x") } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sumBy() {
|
||||
expect(6) { data.sumBy { it.length } }
|
||||
expect(0) { empty.sumBy { it.length } }
|
||||
|
||||
expect(3.0) { data.sumByDouble { it.length.toDouble() / 2 } }
|
||||
expect(0.0) { empty.sumByDouble { it.length.toDouble() / 2 } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun withIndices() {
|
||||
var index = 0
|
||||
for ((i, d) in data.withIndex()) {
|
||||
assertEquals(i, index)
|
||||
assertEquals(d, data.elementAt(index))
|
||||
index++
|
||||
}
|
||||
assertEquals(data.count(), index)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fold() {
|
||||
expect(231) { data.fold(1, { a, b -> a + if (b == "foo") 200 else 30 }) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun reduce() {
|
||||
val reduced = data.reduce { a, b -> a + b }
|
||||
assertEquals(6, reduced.length)
|
||||
assertTrue(reduced == "foobar" || reduced == "barfoo")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapAndJoinToString() {
|
||||
val result = data.joinToString(separator = "-") { it.toUpperCase() }
|
||||
assertEquals("FOO-BAR", result)
|
||||
}
|
||||
|
||||
fun testPlus(doPlus: (Iterable<String>) -> List<String>) {
|
||||
val result: List<String> = doPlus(data)
|
||||
assertEquals(listOf("foo", "bar", "zoo", "g"), result)
|
||||
assertFalse(result === data)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun plusElement() = testPlus { it + "zoo" + "g" }
|
||||
@Test
|
||||
fun plusCollection() = testPlus { it + listOf("zoo", "g") }
|
||||
@Test
|
||||
fun plusArray() = testPlus { it + arrayOf("zoo", "g") }
|
||||
@Test
|
||||
fun plusSequence() = testPlus { it + sequenceOf("zoo", "g") }
|
||||
|
||||
@Test
|
||||
fun plusAssign() {
|
||||
// lets use a mutable variable
|
||||
var result: Iterable<String> = data
|
||||
result += "foo"
|
||||
result += listOf("beer")
|
||||
result += arrayOf("cheese", "wine")
|
||||
result += sequenceOf("zoo", "g")
|
||||
assertEquals(listOf("foo", "bar", "foo", "beer", "cheese", "wine", "zoo", "g"), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun minusElement() {
|
||||
val result = data - "foo" - "g"
|
||||
assertEquals(listOf("bar"), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun minusCollection() {
|
||||
val result = data - listOf("foo", "g")
|
||||
assertEquals(listOf("bar"), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun minusArray() {
|
||||
val result = data - arrayOf("foo", "g")
|
||||
assertEquals(listOf("bar"), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun minusSequence() {
|
||||
val result = data - sequenceOf("foo", "g")
|
||||
assertEquals(listOf("bar"), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun minusAssign() {
|
||||
// lets use a mutable variable
|
||||
var result: Iterable<String> = data
|
||||
result -= "foo"
|
||||
assertEquals(listOf("bar"), result as? List)
|
||||
result = data
|
||||
result -= listOf("beer", "bar")
|
||||
assertEquals(listOf("foo"), result as? List)
|
||||
result = data
|
||||
result -= arrayOf("bar", "foo")
|
||||
assertEquals(emptyList<String>(), result as? List)
|
||||
result = data
|
||||
result -= sequenceOf("foo", "g")
|
||||
assertEquals(listOf("bar"), result as? List)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun <T> Iterable<T>.assertSorted(isInOrder: (T, T) -> Boolean): Unit { this.iterator().assertSorted(isInOrder) }
|
||||
fun <T> Iterator<T>.assertSorted(isInOrder: (T, T) -> Boolean) {
|
||||
if (!hasNext()) return
|
||||
var index = 0
|
||||
var prev = next()
|
||||
while (hasNext()) {
|
||||
index += 1
|
||||
val next = next()
|
||||
assertTrue(isInOrder(prev, next), "Not in order at position $index, element[${index-1}]: $prev, element[$index]: $next")
|
||||
prev = next
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package test.collections
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class IteratorsTest {
|
||||
@Test fun iterationOverIterator() {
|
||||
val c = listOf(0, 1, 2, 3, 4, 5)
|
||||
var s = ""
|
||||
for (i in c.iterator()) {
|
||||
s = s + i.toString()
|
||||
}
|
||||
assertEquals("012345", s)
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package test.collections.binarySearch
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.comparisons.*
|
||||
|
||||
class ListBinarySearchTest {
|
||||
|
||||
val values = listOf(1, 3, 7, 10, 12, 15, 22, 45)
|
||||
|
||||
fun notFound(index: Int) = -(index + 1)
|
||||
|
||||
private val comparator = compareBy<IncomparableDataItem<Int>?> { it?.value }
|
||||
|
||||
@Test
|
||||
fun binarySearchByElement() {
|
||||
val list = values
|
||||
list.forEachIndexed { index, item ->
|
||||
assertEquals(index, list.binarySearch(item))
|
||||
assertEquals(notFound(index), list.binarySearch(item.pred()))
|
||||
assertEquals(notFound(index + 1), list.binarySearch(item.succ()))
|
||||
|
||||
if (index > 0) {
|
||||
index.let { from -> assertEquals(notFound(from), list.binarySearch(list.first(), fromIndex = from)) }
|
||||
(list.size - index).let { to -> assertEquals(notFound(to), list.binarySearch(list.last(), toIndex = to)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun binarySearchByElementNullable() {
|
||||
val list = listOf(null) + values
|
||||
list.forEachIndexed { index, item ->
|
||||
assertEquals(index, list.binarySearch(item))
|
||||
|
||||
if (index > 0) {
|
||||
index.let { from -> assertEquals(notFound(from), list.binarySearch(list.first(), fromIndex = from)) }
|
||||
(list.size - index).let { to -> assertEquals(notFound(to), list.binarySearch(list.last(), toIndex = to)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun binarySearchWithComparator() {
|
||||
val list = values.map { IncomparableDataItem(it) }
|
||||
|
||||
list.forEachIndexed { index, item ->
|
||||
assertEquals(index, list.binarySearch(item, comparator))
|
||||
assertEquals(notFound(index), list.binarySearch(item.pred(), comparator))
|
||||
assertEquals(notFound(index + 1), list.binarySearch(item.succ(), comparator))
|
||||
|
||||
if (index > 0) {
|
||||
index.let { from -> assertEquals(notFound(from), list.binarySearch(list.first(), comparator, fromIndex = from)) }
|
||||
(list.size - index).let { to -> assertEquals(notFound(to), list.binarySearch(list.last(), comparator, toIndex = to)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun binarySearchByKey() {
|
||||
val list = values.map { IncomparableDataItem(it) }
|
||||
|
||||
list.forEachIndexed { index, item ->
|
||||
assertEquals(index, list.binarySearchBy(item.value) { it.value })
|
||||
assertEquals(notFound(index), list.binarySearchBy(item.value.pred()) { it.value })
|
||||
assertEquals(notFound(index + 1), list.binarySearchBy(item.value.succ()) { it.value })
|
||||
|
||||
if (index > 0) {
|
||||
index.let { from -> assertEquals(notFound(from), list.binarySearchBy(list.first().value, fromIndex = from) { it.value }) }
|
||||
(list.size - index).let { to -> assertEquals(notFound(to), list.binarySearchBy(list.last().value, toIndex = to) { it.value }) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun binarySearchByKeyWithComparator() {
|
||||
val list = values.map { IncomparableDataItem(IncomparableDataItem(it)) }
|
||||
|
||||
list.forEachIndexed { index, item ->
|
||||
assertEquals(index, list.binarySearch { comparator.compare(it.value, item.value) } )
|
||||
assertEquals(notFound(index), list.binarySearch { comparator.compare(it.value, item.value.pred()) })
|
||||
assertEquals(notFound(index + 1), list.binarySearch { comparator.compare(it.value, item.value.succ()) })
|
||||
|
||||
if (index > 0) {
|
||||
index.let { from ->
|
||||
assertEquals(notFound(from), list.binarySearch(fromIndex = from) { comparator.compare(it.value, list.first().value) })
|
||||
}
|
||||
(list.size - index).let { to ->
|
||||
assertEquals(notFound(to), list.binarySearch(toIndex = to) { comparator.compare(it.value, list.last().value) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun binarySearchByMultipleKeys() {
|
||||
val list = values.flatMap { v1 -> values.map { v2 -> Pair(v1, v2) } }
|
||||
|
||||
list.forEachIndexed { index, item ->
|
||||
assertEquals(index, list.binarySearch { compareValuesBy(it, item, { it.first }, { it.second }) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private data class IncomparableDataItem<T>(public val value: T)
|
||||
private fun IncomparableDataItem<Int>.pred(): IncomparableDataItem<Int> = IncomparableDataItem(value - 1)
|
||||
private fun IncomparableDataItem<Int>.succ(): IncomparableDataItem<Int> = IncomparableDataItem(value + 1)
|
||||
private fun Int.pred() = dec()
|
||||
private fun Int.succ() = inc()
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
package test.collections
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class ListSpecificTest {
|
||||
val data = listOf("foo", "bar")
|
||||
val empty = listOf<String>()
|
||||
|
||||
@Test
|
||||
fun _toString() {
|
||||
assertEquals("[foo, bar]", data.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tail() {
|
||||
val data = listOf("foo", "bar", "whatnot")
|
||||
val actual = data.drop(1)
|
||||
assertEquals(listOf("bar", "whatnot"), actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun slice() {
|
||||
val list = listOf('A', 'B', 'C', 'D')
|
||||
// ABCD
|
||||
// 0123
|
||||
assertEquals(listOf('B', 'C', 'D'), list.slice(1..3))
|
||||
assertEquals(listOf('D', 'C', 'B'), list.slice(3 downTo 1))
|
||||
|
||||
val iter = listOf(2, 0, 3)
|
||||
assertEquals(listOf('C', 'A', 'D'), list.slice(iter))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getOr() {
|
||||
expect("foo") { data.get(0) }
|
||||
expect("bar") { data.get(1) }
|
||||
assertFails { data.get(2) }
|
||||
assertFails { data.get(-1) }
|
||||
assertFails { empty.get(0) }
|
||||
|
||||
expect("foo") { data.getOrElse(0, {""} )}
|
||||
expect("zoo") { data.getOrElse(-1, { "zoo" })}
|
||||
expect("zoo") { data.getOrElse(2, { "zoo" })}
|
||||
expect("zoo") { empty.getOrElse(0) { "zoo" }}
|
||||
|
||||
expect(null) { empty.getOrNull(0) }
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun lastIndex() {
|
||||
assertEquals(-1, empty.lastIndex)
|
||||
assertEquals(1, data.lastIndex)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun indexOfLast() {
|
||||
expect(-1) { data.indexOfLast { it.contains("p") } }
|
||||
expect(1) { data.indexOfLast { it.length == 3 } }
|
||||
expect(-1) { empty.indexOfLast { it.startsWith('f') } }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mutableList() {
|
||||
val items = listOf("beverage", "location", "name")
|
||||
|
||||
var list = listOf<String>()
|
||||
for (item in items) {
|
||||
list += item
|
||||
}
|
||||
|
||||
assertEquals(3, list.size)
|
||||
assertEquals("beverage,location,name", list.joinToString(","))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNullToString() {
|
||||
assertEquals("[null]", listOf<String?>(null).toString())
|
||||
}
|
||||
}
|
||||
@@ -1,485 +0,0 @@
|
||||
package test.collections
|
||||
|
||||
import kotlin.test.*
|
||||
import test.*
|
||||
|
||||
class MapTest {
|
||||
|
||||
@Test fun getOrElse() {
|
||||
val data = mapOf<String, Int>()
|
||||
val a = data.getOrElse("foo") { 2 }
|
||||
assertEquals(2, a)
|
||||
val a1 = data.getOrElse("foo") { data.get("bar") } ?: 1
|
||||
assertEquals(1, a1)
|
||||
|
||||
val b = data.getOrElse("foo") { 3 }
|
||||
assertEquals(3, b)
|
||||
assertEquals(0, data.size)
|
||||
|
||||
val empty = mapOf<String, Int?>()
|
||||
val c = empty.getOrElse("") { null }
|
||||
assertEquals(null, c)
|
||||
|
||||
val nullable = mapOf(1 to null)
|
||||
val d = nullable.getOrElse(1) { "x" }
|
||||
assertEquals("x", d)
|
||||
}
|
||||
|
||||
@Test fun getValue() {
|
||||
val data: MutableMap<String, Int> = hashMapOf("bar" to 1)
|
||||
assertFailsWith<NoSuchElementException> { data.getValue("foo") }.let { e ->
|
||||
assertTrue("foo" in e.message!!)
|
||||
}
|
||||
assertEquals(1, data.getValue("bar"))
|
||||
|
||||
val mutableWithDefault = data.withDefault { 42 }
|
||||
assertEquals(42, mutableWithDefault.getValue("foo"))
|
||||
|
||||
// verify that it is wrapper
|
||||
mutableWithDefault["bar"] = 2
|
||||
assertEquals(2, data["bar"])
|
||||
data["bar"] = 3
|
||||
assertEquals(3, mutableWithDefault["bar"])
|
||||
|
||||
val readonlyWithDefault = (data as Map<String, Int>).withDefault { it.length }
|
||||
assertEquals(4, readonlyWithDefault.getValue("loop"))
|
||||
|
||||
val withReplacedDefault = readonlyWithDefault.withDefault { 42 }
|
||||
assertEquals(42, withReplacedDefault.getValue("loop"))
|
||||
}
|
||||
|
||||
@Test fun getOrPut() {
|
||||
val data = hashMapOf<String, Int>()
|
||||
val a = data.getOrPut("foo") { 2 }
|
||||
assertEquals(2, a)
|
||||
|
||||
val b = data.getOrPut("foo") { 3 }
|
||||
assertEquals(2, b)
|
||||
|
||||
assertEquals(1, data.size)
|
||||
|
||||
val empty = hashMapOf<String, Int?>()
|
||||
val c = empty.getOrPut("") { null }
|
||||
assertEquals(null, c)
|
||||
|
||||
val d = empty.getOrPut("") { 1 }
|
||||
assertEquals(1, d)
|
||||
}
|
||||
|
||||
@Test fun sizeAndEmpty() {
|
||||
val data = hashMapOf<String, Int>()
|
||||
assertTrue { data.none() }
|
||||
assertEquals(data.size, 0)
|
||||
}
|
||||
|
||||
@Test fun setViaIndexOperators() {
|
||||
val map = hashMapOf<String, String>()
|
||||
assertTrue { map.none() }
|
||||
assertEquals(map.size, 0)
|
||||
|
||||
map["name"] = "James"
|
||||
|
||||
assertTrue { map.any() }
|
||||
assertEquals(map.size, 1)
|
||||
assertEquals("James", map["name"])
|
||||
}
|
||||
|
||||
@Test fun iterate() {
|
||||
val map = mapOf("beverage" to "beer", "location" to "Mells", "name" to "James")
|
||||
val list = arrayListOf<String>()
|
||||
for (e in map) {
|
||||
list.add(e.key)
|
||||
list.add(e.value)
|
||||
}
|
||||
|
||||
assertEquals(6, list.size)
|
||||
assertEquals("beverage,beer,location,Mells,name,James", list.joinToString(","))
|
||||
}
|
||||
|
||||
@Test fun iterateAndMutate() {
|
||||
val map = mutableMapOf("beverage" to "beer", "location" to "Mells", "name" to "James")
|
||||
val it = map.iterator()
|
||||
for (e in it) {
|
||||
when (e.key) {
|
||||
"beverage" -> e.setValue("juice")
|
||||
"location" -> it.remove()
|
||||
}
|
||||
}
|
||||
assertEquals(mapOf("beverage" to "juice", "name" to "James"), map)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun onEach() {
|
||||
val map = mutableMapOf("beverage" to "beer", "location" to "Mells")
|
||||
val result = StringBuilder()
|
||||
val newMap = map.onEach { result.append(it.key).append("=").append(it.value).append(";") }
|
||||
assertEquals("beverage=beer;location=Mells;", result.toString())
|
||||
assertTrue(map === newMap)
|
||||
|
||||
// static types test
|
||||
assertStaticTypeIs<HashMap<String, String>>(
|
||||
hashMapOf("a" to "b").onEach { }
|
||||
)
|
||||
}
|
||||
|
||||
@Test fun stream() {
|
||||
val map = mapOf("beverage" to "beer", "location" to "Mells", "name" to "James")
|
||||
val named = map.asSequence().filter { it.key == "name" }.single()
|
||||
assertEquals("James", named.value)
|
||||
}
|
||||
|
||||
@Test fun iterateWithProperties() {
|
||||
val map = mapOf("beverage" to "beer", "location" to "Mells", "name" to "James")
|
||||
val list = arrayListOf<String>()
|
||||
for (e in map) {
|
||||
list.add(e.key)
|
||||
list.add(e.value)
|
||||
}
|
||||
|
||||
assertEquals(6, list.size)
|
||||
assertEquals("beverage,beer,location,Mells,name,James", list.joinToString(","))
|
||||
}
|
||||
|
||||
@Test fun iterateWithExtraction() {
|
||||
val map = mapOf("beverage" to "beer", "location" to "Mells", "name" to "James")
|
||||
val list = arrayListOf<String>()
|
||||
for ((key, value) in map) {
|
||||
list.add(key)
|
||||
list.add(value)
|
||||
}
|
||||
|
||||
assertEquals(6, list.size)
|
||||
assertEquals("beverage,beer,location,Mells,name,James", list.joinToString(","))
|
||||
}
|
||||
|
||||
@Test fun contains() {
|
||||
val map = mapOf("a" to 1, "b" to 2)
|
||||
assertTrue("a" in map)
|
||||
assertTrue("c" !in map)
|
||||
}
|
||||
|
||||
@Test fun map() {
|
||||
val m1 = mapOf("beverage" to "beer", "location" to "Mells")
|
||||
val list = m1.map { it.value + " rocks" }
|
||||
|
||||
assertEquals(listOf("beer rocks", "Mells rocks"), list)
|
||||
}
|
||||
|
||||
|
||||
@Test fun mapNotNull() {
|
||||
val m1 = mapOf("a" to 1, "b" to null)
|
||||
val list = m1.mapNotNull { it.value?.let { v -> "${it.key}$v" } }
|
||||
assertEquals(listOf("a1"), list)
|
||||
}
|
||||
|
||||
@Test fun mapValues() {
|
||||
val m1 = mapOf("beverage" to "beer", "location" to "Mells")
|
||||
val m2 = m1.mapValues { it.value + "2" }
|
||||
|
||||
assertEquals(mapOf("beverage" to "beer2", "location" to "Mells2"), m2)
|
||||
|
||||
val m1p: Map<out String, String> = m1
|
||||
val m3 = m1p.mapValuesTo(hashMapOf()) { it.value.length }
|
||||
assertStaticTypeIs<HashMap<String, Int>>(m3)
|
||||
assertEquals(mapOf("beverage" to 4, "location" to 5), m3)
|
||||
}
|
||||
|
||||
@Test fun mapKeys() {
|
||||
val m1 = mapOf("beverage" to "beer", "location" to "Mells")
|
||||
val m2 = m1.mapKeys { it.key + "2" }
|
||||
|
||||
assertEquals(mapOf("beverage2" to "beer", "location2" to "Mells"), m2)
|
||||
|
||||
val m1p: Map<out String, String> = m1
|
||||
val m3 = m1p.mapKeysTo(mutableMapOf()) { it.key.length }
|
||||
assertStaticTypeIs<MutableMap<Int, String>>(m3)
|
||||
assertEquals(mapOf(8 to "Mells"), m3)
|
||||
}
|
||||
|
||||
@Test fun createFrom() {
|
||||
val pairs = arrayOf("a" to 1, "b" to 2)
|
||||
val expected = mapOf(*pairs)
|
||||
|
||||
assertEquals(expected, pairs.toMap())
|
||||
assertEquals(expected, pairs.asIterable().toMap())
|
||||
assertEquals(expected, pairs.asSequence().toMap())
|
||||
assertEquals(expected, expected.toMap())
|
||||
assertEquals(mapOf("a" to 1), expected.filterKeys { it == "a" }.toMap())
|
||||
assertEquals(emptyMap(), expected.filter { false }.toMap())
|
||||
|
||||
val mutableMap = expected.toMutableMap()
|
||||
assertEquals(expected, mutableMap)
|
||||
mutableMap += "c" to 3
|
||||
assertNotEquals(expected, mutableMap)
|
||||
}
|
||||
|
||||
@Test fun populateTo() {
|
||||
val pairs = arrayOf("a" to 1, "b" to 2)
|
||||
val expected = mapOf(*pairs)
|
||||
|
||||
val linkedMap: LinkedHashMap<String, Int> = pairs.toMap(linkedMapOf())
|
||||
assertEquals(expected, linkedMap)
|
||||
|
||||
val hashMap: HashMap<String, Int> = pairs.asIterable().toMap(hashMapOf())
|
||||
assertEquals(expected, hashMap)
|
||||
|
||||
val mutableMap: MutableMap<String, Int> = pairs.asSequence().toMap(mutableMapOf())
|
||||
assertEquals(expected, mutableMap)
|
||||
|
||||
val mutableMap2 = mutableMap.toMap(mutableMapOf())
|
||||
assertEquals(expected, mutableMap2)
|
||||
|
||||
val mutableMap3 = mutableMap.toMap(hashMapOf<CharSequence, Any>())
|
||||
assertEquals<Map<*, *>>(expected, mutableMap3)
|
||||
}
|
||||
|
||||
@Test fun createWithSelector() {
|
||||
val map = listOf("a", "bb", "ccc").associateBy { it.length }
|
||||
assertEquals(3, map.size)
|
||||
assertEquals("a", map.get(1))
|
||||
assertEquals("bb", map.get(2))
|
||||
assertEquals("ccc", map.get(3))
|
||||
}
|
||||
|
||||
@Test fun createWithSelectorAndOverwrite() {
|
||||
val map = listOf("aa", "bb", "ccc").associateBy { it.length }
|
||||
assertEquals(2, map.size)
|
||||
assertEquals("bb", map.get(2))
|
||||
assertEquals("ccc", map.get(3))
|
||||
}
|
||||
|
||||
@Test fun createWithSelectorForKeyAndValue() {
|
||||
val map = listOf("a", "bb", "ccc").associateBy({ it.length }, { it.toUpperCase() })
|
||||
assertEquals(3, map.size)
|
||||
assertEquals("A", map[1])
|
||||
assertEquals("BB", map[2])
|
||||
assertEquals("CCC", map[3])
|
||||
}
|
||||
|
||||
@Test fun createWithPairSelector() {
|
||||
val map = listOf("a", "bb", "ccc").associate { it.length to it.toUpperCase() }
|
||||
assertEquals(3, map.size)
|
||||
assertEquals("A", map[1])
|
||||
assertEquals("BB", map[2])
|
||||
assertEquals("CCC", map[3])
|
||||
}
|
||||
|
||||
@Test fun createUsingTo() {
|
||||
val map = mapOf("a" to 1, "b" to 2)
|
||||
assertEquals(2, map.size)
|
||||
assertEquals(1, map["a"])
|
||||
assertEquals(2, map["b"])
|
||||
}
|
||||
|
||||
@Test fun createMutableMap() {
|
||||
val map = mutableMapOf("b" to 1, "c" to 2)
|
||||
map.put("a", 3)
|
||||
assertEquals(listOf("b" to 1, "c" to 2, "a" to 3), map.toList())
|
||||
}
|
||||
|
||||
@Test fun createLinkedMap() {
|
||||
val map = linkedMapOf(Pair("c", 3), Pair("b", 2), Pair("a", 1))
|
||||
assertEquals(1, map["a"])
|
||||
assertEquals(2, map["b"])
|
||||
assertEquals(3, map["c"])
|
||||
assertEquals(listOf("c", "b", "a"), map.keys.toList())
|
||||
}
|
||||
|
||||
@Test fun filter() {
|
||||
val map = mapOf(Pair("b", 3), Pair("c", 2), Pair("a", 2))
|
||||
val filteredByKey = map.filter { it.key[0] == 'b' }
|
||||
assertEquals(mapOf("b" to 3), filteredByKey)
|
||||
|
||||
val filteredByKey2 = map.filterKeys { it[0] == 'b' }
|
||||
assertEquals(mapOf("b" to 3), filteredByKey2)
|
||||
|
||||
val filteredByValue = map.filter { it.value == 2 }
|
||||
assertEquals(mapOf("a" to 2, "c" to 2), filteredByValue)
|
||||
|
||||
val filteredByValue2 = map.filterValues { it % 2 == 0 }
|
||||
assertEquals(mapOf("a" to 2, "c" to 2), filteredByValue2)
|
||||
}
|
||||
|
||||
@Test fun filterOutProjectedTo() {
|
||||
val map: Map<out String, Int> = mapOf(Pair("b", 3), Pair("c", 2), Pair("a", 2))
|
||||
|
||||
val filteredByKey = map.filterTo(mutableMapOf()) { it.key[0] == 'b' }
|
||||
assertStaticTypeIs<MutableMap<String, Int>>(filteredByKey)
|
||||
assertEquals(mapOf("b" to 3), filteredByKey)
|
||||
|
||||
val filteredByKey2 = map.filterKeys { it[0] == 'b' }
|
||||
assertStaticTypeIs<Map<String, Int>>(filteredByKey2)
|
||||
assertEquals(mapOf("b" to 3), filteredByKey2)
|
||||
|
||||
val filteredByValue = map.filterNotTo(hashMapOf()) { it.value != 2 }
|
||||
assertStaticTypeIs<HashMap<String, Int>>(filteredByValue)
|
||||
assertEquals(mapOf("a" to 2, "c" to 2), filteredByValue)
|
||||
|
||||
val filteredByValue2 = map.filterValues { it % 2 == 0 }
|
||||
assertStaticTypeIs<Map<String, Int>>(filteredByValue2)
|
||||
assertEquals(mapOf("a" to 2, "c" to 2), filteredByValue2)
|
||||
}
|
||||
|
||||
@Test fun any() {
|
||||
val map = mapOf(Pair("b", 3), Pair("c", 2), Pair("a", 2))
|
||||
assertTrue(map.any())
|
||||
assertFalse(emptyMap<String, Int>().any())
|
||||
|
||||
assertTrue(map.any { it.key == "b" })
|
||||
assertFalse(emptyMap<String, Int>().any { it.key == "b" })
|
||||
|
||||
assertTrue(map.any { it.value == 2 })
|
||||
assertFalse(map.any { it.value == 5 })
|
||||
}
|
||||
|
||||
@Test fun all() {
|
||||
val map = mapOf(Pair("b", 3), Pair("c", 2), Pair("a", 2))
|
||||
assertTrue(map.all { it.key != "d" })
|
||||
assertTrue(emptyMap<String, Int>().all { it.key == "d" })
|
||||
|
||||
assertTrue(map.all { it.value > 0 })
|
||||
assertFalse(map.all { it.value == 2 })
|
||||
}
|
||||
|
||||
@Test fun countBy() {
|
||||
val map = mapOf(Pair("b", 3), Pair("c", 2), Pair("a", 2))
|
||||
assertEquals(3, map.count())
|
||||
|
||||
val filteredByKey = map.count { it.key == "b" }
|
||||
assertEquals(1, filteredByKey)
|
||||
|
||||
val filteredByValue = map.count { it.value == 2 }
|
||||
assertEquals(2, filteredByValue)
|
||||
}
|
||||
|
||||
@Test fun filterNot() {
|
||||
val map = mapOf(Pair("b", 3), Pair("c", 2), Pair("a", 2))
|
||||
val filteredByKey = map.filterNot { it.key == "b" }
|
||||
assertEquals(2, filteredByKey.size)
|
||||
assertEquals(null, filteredByKey["b"])
|
||||
assertEquals(2, filteredByKey["c"])
|
||||
assertEquals(2, filteredByKey["a"])
|
||||
|
||||
val filteredByValue = map.filterNot { it.value == 2 }
|
||||
assertEquals(1, filteredByValue.size)
|
||||
assertEquals(3, filteredByValue["b"])
|
||||
}
|
||||
|
||||
fun testPlusAssign(doPlusAssign: (MutableMap<String, Int>) -> Unit) {
|
||||
val map = hashMapOf("a" to 1, "b" to 2)
|
||||
doPlusAssign(map)
|
||||
assertEquals(3, map.size)
|
||||
assertEquals(1, map["a"])
|
||||
assertEquals(4, map["b"])
|
||||
assertEquals(3, map["c"])
|
||||
}
|
||||
|
||||
@Test fun plusAssign() = testPlusAssign {
|
||||
it += "b" to 4
|
||||
it += "c" to 3
|
||||
}
|
||||
|
||||
@Test fun plusAssignList() = testPlusAssign { it += listOf("c" to 3, "b" to 4) }
|
||||
|
||||
@Test fun plusAssignArray() = testPlusAssign { it += arrayOf("c" to 3, "b" to 4) }
|
||||
|
||||
@Test fun plusAssignSequence() = testPlusAssign { it += sequenceOf("c" to 3, "b" to 4) }
|
||||
|
||||
@Test fun plusAssignMap() = testPlusAssign { it += mapOf("c" to 3, "b" to 4) }
|
||||
|
||||
fun testPlus(doPlus: (Map<String, Int>) -> Map<String, Int>) {
|
||||
val original = mapOf("A" to 1, "B" to 2)
|
||||
val extended = doPlus(original)
|
||||
assertEquals(3, extended.size)
|
||||
assertEquals(1, extended["A"])
|
||||
assertEquals(4, extended["B"])
|
||||
assertEquals(3, extended["C"])
|
||||
}
|
||||
|
||||
@Test fun plus() = testPlus { it + ("C" to 3) + ("B" to 4) }
|
||||
|
||||
@Test fun plusList() = testPlus { it + listOf("C" to 3, "B" to 4) }
|
||||
|
||||
@Test fun plusArray() = testPlus { it + arrayOf("C" to 3, "B" to 4) }
|
||||
|
||||
@Test fun plusSequence() = testPlus { it + sequenceOf("C" to 3, "B" to 4) }
|
||||
|
||||
@Test fun plusMap() = testPlus { it + mapOf("C" to 3, "B" to 4) }
|
||||
|
||||
@Test fun plusAny() {
|
||||
testPlusAny(emptyMap<String, String>(), 1 to "A")
|
||||
testPlusAny(mapOf("A" to null), "A" as CharSequence to 2)
|
||||
}
|
||||
|
||||
fun <K, V> testPlusAny(mapObject: Any, pair: Pair<K, V>) {
|
||||
val map = mapObject as Map<*, *>
|
||||
fun assertContains(map: Map<*, *>) = assertEquals(pair.second, map[pair.first])
|
||||
|
||||
assertContains(map + pair)
|
||||
assertContains(map + listOf(pair))
|
||||
assertContains(map + arrayOf(pair))
|
||||
assertContains(map + sequenceOf(pair))
|
||||
assertContains(map + mapOf(pair))
|
||||
}
|
||||
|
||||
|
||||
fun testMinus(doMinus: (Map<String, Int>) -> Map<String, Int>) {
|
||||
val original = mapOf("A" to 1, "B" to 2)
|
||||
val shortened = doMinus(original)
|
||||
assertEquals("A" to 1, shortened.entries.single().toPair())
|
||||
}
|
||||
|
||||
@Test fun minus() = testMinus { it - "B" - "C" }
|
||||
|
||||
@Test fun minusList() = testMinus { it - listOf("B", "C") }
|
||||
|
||||
@Test fun minusArray() = testMinus { it - arrayOf("B", "C") }
|
||||
|
||||
@Test fun minusSequence() = testMinus { it - sequenceOf("B", "C") }
|
||||
|
||||
@Test fun minusSet() = testMinus { it - setOf("B", "C") }
|
||||
|
||||
|
||||
|
||||
fun testMinusAssign(doMinusAssign: (MutableMap<String, Int>) -> Unit) {
|
||||
val original = hashMapOf("A" to 1, "B" to 2)
|
||||
doMinusAssign(original)
|
||||
assertEquals("A" to 1, original.entries.single().toPair())
|
||||
}
|
||||
|
||||
@Test fun minusAssign() = testMinusAssign {
|
||||
it -= "B"
|
||||
it -= "C"
|
||||
}
|
||||
|
||||
@Test fun minusAssignList() = testMinusAssign { it -= listOf("B", "C") }
|
||||
|
||||
@Test fun minusAssignArray() = testMinusAssign { it -= arrayOf("B", "C") }
|
||||
|
||||
@Test fun minusAssignSequence() = testMinusAssign { it -= sequenceOf("B", "C") }
|
||||
|
||||
|
||||
fun testIdempotent(operation: (Map<String, Int>) -> Map<String, Int>) {
|
||||
val original = mapOf("A" to 1, "B" to 2)
|
||||
assertEquals(original, operation(original))
|
||||
}
|
||||
|
||||
fun testIdempotentAssign(operation: (MutableMap<String, Int>) -> Unit) {
|
||||
val original = hashMapOf("A" to 1, "B" to 2)
|
||||
val result = HashMap(original)
|
||||
operation(result)
|
||||
assertEquals(original, result)
|
||||
}
|
||||
|
||||
|
||||
@Test fun plusEmptyList() = testIdempotent { it + listOf() }
|
||||
|
||||
@Test fun plusEmptySet() = testIdempotent { it + setOf() }
|
||||
|
||||
@Test fun plusAssignEmptyList() = testIdempotentAssign { it += listOf() }
|
||||
|
||||
@Test fun plusAssignEmptySet() = testIdempotentAssign { it += setOf() }
|
||||
|
||||
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package test.collections
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
|
||||
class MutableCollectionTest {
|
||||
fun <T, C: MutableCollection<T>> testOperation(before: List<T>, after: List<T>, expectedModified: Boolean, toMutableCollection: (List<T>) -> C)
|
||||
= fun(operation: (C.() -> Boolean)) {
|
||||
val list = toMutableCollection(before)
|
||||
assertEquals(expectedModified, list.operation())
|
||||
assertEquals(toMutableCollection(after), list)
|
||||
}
|
||||
|
||||
fun <T> testOperation(before: List<T>, after: List<T>, expectedModified: Boolean)
|
||||
= testOperation(before, after, expectedModified, { it.toMutableList() })
|
||||
|
||||
|
||||
@Test fun addAll() {
|
||||
val data = listOf("foo", "bar")
|
||||
|
||||
testOperation(emptyList(), data, true).let { assertAdd ->
|
||||
assertAdd { addAll(data) }
|
||||
assertAdd { addAll(data.toTypedArray()) }
|
||||
assertAdd { addAll(data.toTypedArray().asIterable()) }
|
||||
assertAdd { addAll(data.asSequence()) }
|
||||
}
|
||||
|
||||
testOperation(data, data, false, { it.toCollection(LinkedHashSet()) }).let { assertAdd ->
|
||||
assertAdd { addAll(data) }
|
||||
assertAdd { addAll(data.toTypedArray()) }
|
||||
assertAdd { addAll(data.toTypedArray().asIterable()) }
|
||||
assertAdd { addAll(data.asSequence()) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun removeAll() {
|
||||
val content = listOf("foo", "bar", "bar")
|
||||
val data = listOf("bar")
|
||||
val expected = listOf("foo")
|
||||
|
||||
testOperation(content, expected, true).let { assertRemove ->
|
||||
assertRemove { removeAll(data) }
|
||||
assertRemove { removeAll(data.toTypedArray()) }
|
||||
assertRemove { removeAll(data.toTypedArray().asIterable()) }
|
||||
assertRemove { removeAll { it in data } }
|
||||
assertRemove { (this as MutableIterable<String>).removeAll { it in data } }
|
||||
val predicate = { cs: CharSequence -> cs.first() == 'b' }
|
||||
assertRemove { removeAll(predicate) }
|
||||
}
|
||||
|
||||
|
||||
testOperation(content, content, false).let { assertRemove ->
|
||||
assertRemove { removeAll(emptyList()) }
|
||||
assertRemove { removeAll(emptyArray()) }
|
||||
assertRemove { removeAll(emptySequence()) }
|
||||
assertRemove { removeAll { false } }
|
||||
assertRemove { (this as MutableIterable<String>).removeAll { false } }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun retainAll() {
|
||||
val content = listOf("foo", "bar", "bar")
|
||||
val expected = listOf("bar", "bar")
|
||||
|
||||
testOperation(content, expected, true).let { assertRetain ->
|
||||
val data = listOf("bar")
|
||||
assertRetain { retainAll(data) }
|
||||
assertRetain { retainAll(data.toTypedArray()) }
|
||||
assertRetain { retainAll(data.toTypedArray().asIterable()) }
|
||||
assertRetain { retainAll(data.asSequence()) }
|
||||
assertRetain { retainAll { it in data } }
|
||||
assertRetain { (this as MutableIterable<String>).retainAll { it in data } }
|
||||
|
||||
val predicate = { cs: CharSequence -> cs.first() == 'b' }
|
||||
assertRetain { retainAll(predicate) }
|
||||
}
|
||||
testOperation(content, emptyList(), true).let { assertRetain ->
|
||||
val data = emptyList<String>()
|
||||
assertRetain { retainAll(data) }
|
||||
assertRetain { retainAll(data.toTypedArray()) }
|
||||
assertRetain { retainAll(data.toTypedArray().asIterable()) }
|
||||
assertRetain { retainAll(data.asSequence()) }
|
||||
assertRetain { retainAll { it in data } }
|
||||
assertRetain { (this as MutableIterable<String>).retainAll { it in data } }
|
||||
}
|
||||
testOperation(emptyList<String>(), emptyList(), false).let { assertRetain ->
|
||||
val data = emptyList<String>()
|
||||
assertRetain { retainAll(data) }
|
||||
assertRetain { retainAll(data.toTypedArray()) }
|
||||
assertRetain { retainAll(data.toTypedArray().asIterable()) }
|
||||
assertRetain { retainAll(data.asSequence()) }
|
||||
assertRetain { retainAll { it in data } }
|
||||
assertRetain { (this as MutableIterable<String>).retainAll { it in data } }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun listFill() {
|
||||
val list = MutableList(3) { it }
|
||||
list.fill(42)
|
||||
assertEquals(listOf(42, 42, 42), list)
|
||||
}
|
||||
|
||||
@Test fun shuffled() {
|
||||
val list = MutableList(100) { it }
|
||||
val shuffled = list.shuffled()
|
||||
|
||||
assertNotEquals(list, shuffled)
|
||||
assertEquals(list.toSet(), shuffled.toSet())
|
||||
assertEquals(list.size, shuffled.distinct().size)
|
||||
}
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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 test.collections
|
||||
|
||||
import test.collections.behaviors.listBehavior
|
||||
import test.collections.compare
|
||||
import kotlin.test.*
|
||||
|
||||
class ReversedViewsTest {
|
||||
|
||||
@Test fun testNullToString() {
|
||||
assertEquals("[null]", listOf<String?>(null).asReversed().toString())
|
||||
}
|
||||
|
||||
@Test fun testBehavior() {
|
||||
val original = listOf(2L, 3L, Long.MAX_VALUE)
|
||||
val reversed = original.reversed()
|
||||
compare(reversed, original.asReversed()) {
|
||||
listBehavior()
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun testSimple() {
|
||||
assertEquals(listOf(3, 2, 1), listOf(1, 2, 3).asReversed())
|
||||
assertEquals(listOf(3, 2, 1), listOf(1, 2, 3).asReversed().toList())
|
||||
}
|
||||
|
||||
@Test fun testRandomAccess() {
|
||||
val reversed = listOf(1, 2, 3).asReversed()
|
||||
|
||||
assertEquals(3, reversed[0])
|
||||
assertEquals(2, reversed[1])
|
||||
assertEquals(1, reversed[2])
|
||||
}
|
||||
|
||||
@Test fun testDoubleReverse() {
|
||||
assertEquals(listOf(1, 2, 3), listOf(1, 2, 3).asReversed().asReversed())
|
||||
assertEquals(listOf(2, 3), listOf(1, 2, 3, 4).asReversed().subList(1, 3).asReversed())
|
||||
}
|
||||
|
||||
@Test fun testEmpty() {
|
||||
assertEquals(emptyList<Int>(), emptyList<Int>().asReversed())
|
||||
}
|
||||
|
||||
@Test fun testReversedSubList() {
|
||||
val reversed = (1..10).toList().asReversed()
|
||||
assertEquals(listOf(9, 8, 7), reversed.subList(1, 4))
|
||||
}
|
||||
|
||||
@Test fun testMutableSubList() {
|
||||
val original = arrayListOf(1, 2, 3, 4)
|
||||
val reversedSubList = original.asReversed().subList(1, 3)
|
||||
|
||||
assertEquals(listOf(3, 2), reversedSubList)
|
||||
reversedSubList.clear()
|
||||
assertEquals(emptyList<Int>(), reversedSubList)
|
||||
assertEquals(listOf(1, 4), original)
|
||||
|
||||
reversedSubList.add(100)
|
||||
assertEquals(listOf(100), reversedSubList)
|
||||
assertEquals(listOf(1, 100, 4), original)
|
||||
}
|
||||
|
||||
@Test fun testMutableSimple() {
|
||||
assertEquals(listOf(3, 2, 1), mutableListOf(1, 2, 3).asReversed())
|
||||
assertEquals(listOf(3, 2, 1), mutableListOf(1, 2, 3).asReversed().toList())
|
||||
}
|
||||
|
||||
@Test fun testMutableDoubleReverse() {
|
||||
assertEquals(listOf(1, 2, 3), mutableListOf(1, 2, 3).asReversed().asReversed())
|
||||
assertEquals(listOf(2, 3), mutableListOf(1, 2, 3, 4).asReversed().subList(1, 3).asReversed())
|
||||
}
|
||||
|
||||
@Test fun testMutableEmpty() {
|
||||
assertEquals(emptyList<Int>(), mutableListOf<Int>().asReversed())
|
||||
}
|
||||
|
||||
@Test fun testMutableReversedSubList() {
|
||||
val reversed = (1..10).toMutableList().asReversed()
|
||||
assertEquals(listOf(9, 8, 7), reversed.subList(1, 4))
|
||||
}
|
||||
|
||||
@Test fun testMutableAdd() {
|
||||
val original = mutableListOf(1, 2, 3)
|
||||
val reversed = original.asReversed()
|
||||
|
||||
reversed.add(0) // add zero at end of reversed
|
||||
assertEquals(listOf(3, 2, 1, 0), reversed)
|
||||
assertEquals(listOf(0, 1, 2, 3), original)
|
||||
|
||||
reversed.add(0, 4) // add four at position 0
|
||||
assertEquals(listOf(4, 3, 2, 1, 0), reversed)
|
||||
assertEquals(listOf(0, 1, 2, 3, 4), original)
|
||||
}
|
||||
|
||||
@Test fun testMutableSet() {
|
||||
val original = mutableListOf(1, 2, 3)
|
||||
val reversed = original.asReversed()
|
||||
|
||||
reversed.set(0, 300)
|
||||
reversed.set(1, 200)
|
||||
reversed.set(2, 100)
|
||||
|
||||
assertEquals(listOf(100, 200, 300), original)
|
||||
assertEquals(listOf(300, 200, 100), reversed)
|
||||
}
|
||||
|
||||
@Test fun testMutableRemove() {
|
||||
val original = mutableListOf("a", "b", "c")
|
||||
val reversed = original.asReversed()
|
||||
|
||||
reversed.removeAt(0) // remove c
|
||||
assertEquals(listOf("a", "b"), original)
|
||||
assertEquals(listOf("b", "a"), reversed)
|
||||
|
||||
reversed.removeAt(1) // remove a
|
||||
assertEquals(listOf("b"), original)
|
||||
|
||||
reversed.removeAt(0) // remove remaining b
|
||||
assertEquals(emptyList<String>(), original)
|
||||
}
|
||||
|
||||
@Test fun testMutableRemoveByObj() {
|
||||
val original = mutableListOf("a", "b", "c")
|
||||
val reversed = original.asReversed()
|
||||
|
||||
reversed.remove("c")
|
||||
assertEquals(listOf("a", "b"), original)
|
||||
assertEquals(listOf("b", "a"), reversed)
|
||||
}
|
||||
|
||||
@Test fun testMutableClear() {
|
||||
val original = mutableListOf(1, 2, 3)
|
||||
val reversed = original.asReversed()
|
||||
|
||||
reversed.clear()
|
||||
|
||||
assertEquals(emptyList<Int>(), reversed)
|
||||
assertEquals(emptyList<Int>(), original)
|
||||
}
|
||||
|
||||
@Test fun testContains() {
|
||||
assertTrue { 1 in listOf(1, 2, 3).asReversed() }
|
||||
assertTrue { 1 in mutableListOf(1, 2, 3).asReversed() }
|
||||
}
|
||||
|
||||
@Test fun testIndexOf() {
|
||||
assertEquals(2, listOf(1, 2, 3).asReversed().indexOf(1))
|
||||
assertEquals(2, mutableListOf(1, 2, 3).asReversed().indexOf(1))
|
||||
}
|
||||
|
||||
@Test fun testBidirectionalModifications() {
|
||||
val original = mutableListOf(1, 2, 3, 4)
|
||||
val reversed = original.asReversed()
|
||||
|
||||
original.removeAt(3)
|
||||
assertEquals(listOf(1, 2, 3), original)
|
||||
assertEquals(listOf(3, 2, 1), reversed)
|
||||
|
||||
reversed.removeAt(2)
|
||||
assertEquals(listOf(2, 3), original)
|
||||
assertEquals(listOf(3, 2), reversed)
|
||||
}
|
||||
|
||||
@Test fun testGetIOOB() {
|
||||
val success = try {
|
||||
listOf(1, 2, 3).asReversed().get(3)
|
||||
true
|
||||
} catch (expected: IndexOutOfBoundsException) {
|
||||
false
|
||||
}
|
||||
|
||||
assertFalse(success)
|
||||
}
|
||||
|
||||
@Test fun testSetIOOB() {
|
||||
val success = try {
|
||||
mutableListOf(1, 2, 3).asReversed().set(3, 0)
|
||||
true
|
||||
} catch(expected: IndexOutOfBoundsException) {
|
||||
false
|
||||
}
|
||||
|
||||
assertFalse(success)
|
||||
}
|
||||
|
||||
@Test fun testAddIOOB() {
|
||||
val success = try {
|
||||
mutableListOf(1, 2, 3).asReversed().add(4, 0)
|
||||
true
|
||||
} catch(expected: IndexOutOfBoundsException) {
|
||||
false
|
||||
}
|
||||
|
||||
assertFalse(success)
|
||||
}
|
||||
|
||||
@Test fun testRemoveIOOB() {
|
||||
val success = try {
|
||||
mutableListOf(1, 2, 3).asReversed().removeAt(3)
|
||||
true
|
||||
} catch(expected: IndexOutOfBoundsException) {
|
||||
false
|
||||
}
|
||||
|
||||
assertFalse(success)
|
||||
}
|
||||
}
|
||||
@@ -1,562 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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 test.collections
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.comparisons.*
|
||||
|
||||
fun fibonacci(): Sequence<Int> {
|
||||
// fibonacci terms
|
||||
// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, ...
|
||||
return generateSequence(Pair(0, 1), { Pair(it.second, it.first + it.second) }).map { it.first * 1 }
|
||||
}
|
||||
|
||||
public class SequenceTest {
|
||||
|
||||
private class TriggerSequence<out T>(val source: Sequence<T>) : Sequence<T> {
|
||||
var iterated: Boolean = false
|
||||
private set
|
||||
|
||||
override fun iterator(): Iterator<T> = source.iterator().also { iterated = true }
|
||||
}
|
||||
|
||||
fun <T> ensureIsIntermediate(source: Sequence<T>, operation: (Sequence<T>) -> Sequence<*>) {
|
||||
TriggerSequence(source).let { s ->
|
||||
val result = operation(s)
|
||||
assertFalse(s.iterated, "Source should not be iterated before the result is")
|
||||
result.iterator().hasNext()
|
||||
assertTrue(s.iterated, "Source should be iterated after the result is iterated")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun filterEmptySequence() {
|
||||
for (sequence in listOf(emptySequence<String>(), sequenceOf<String>())) {
|
||||
assertEquals(0, sequence.filter { false }.count())
|
||||
assertEquals(0, sequence.filter { true }.count())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun mapEmptySequence() {
|
||||
for (sequence in listOf(emptySequence<String>(), sequenceOf<String>())) {
|
||||
assertEquals(0, sequence.map { true }.count())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun requireNoNulls() {
|
||||
val sequence = sequenceOf<String?>("foo", "bar")
|
||||
val notNull = sequence.requireNoNulls()
|
||||
assertEquals(listOf("foo", "bar"), notNull.toList())
|
||||
|
||||
val sequenceWithNulls = sequenceOf("foo", null, "bar")
|
||||
val notNull2 = sequenceWithNulls.requireNoNulls() // shouldn't fail yet
|
||||
assertFails {
|
||||
// should throw an exception as we have a null
|
||||
notNull2.toList()
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun filterIndexed() {
|
||||
assertEquals(listOf(1, 2, 5, 13, 34), fibonacci().filterIndexed { index, _ -> index % 2 == 1 }.take(5).toList())
|
||||
}
|
||||
|
||||
@Test fun filterNullable() {
|
||||
val data = sequenceOf(null, "foo", null, "bar")
|
||||
val filtered = data.filter { it == null || it == "foo" }
|
||||
assertEquals(listOf(null, "foo", null), filtered.toList())
|
||||
}
|
||||
|
||||
@Test fun filterNot() {
|
||||
val data = sequenceOf(null, "foo", null, "bar")
|
||||
val filtered = data.filterNot { it == null }
|
||||
assertEquals(listOf("foo", "bar"), filtered.toList())
|
||||
}
|
||||
|
||||
@Test fun filterNotNull() {
|
||||
val data = sequenceOf(null, "foo", null, "bar")
|
||||
val filtered = data.filterNotNull()
|
||||
assertEquals(listOf("foo", "bar"), filtered.toList())
|
||||
}
|
||||
|
||||
@Test fun mapIndexed() {
|
||||
assertEquals(listOf(0, 1, 2, 6, 12), fibonacci().mapIndexed { index, value -> index * value }.takeWhile { i: Int -> i < 20 }.toList())
|
||||
}
|
||||
|
||||
@Test fun mapNotNull() {
|
||||
assertEquals(listOf(0, 10, 110, 1220), fibonacci().mapNotNull { if (it % 5 == 0) it * 2 else null }.take(4).toList())
|
||||
}
|
||||
|
||||
@Test fun mapIndexedNotNull() {
|
||||
// find which terms are divisible by their index
|
||||
assertEquals(listOf("1/1", "5/5", "144/12", "46368/24", "75025/25"),
|
||||
fibonacci().mapIndexedNotNull { index, value ->
|
||||
if (index > 0 && (value % index) == 0) "$value/$index" else null
|
||||
}.take(5).toList())
|
||||
}
|
||||
|
||||
|
||||
@Test fun mapAndJoinToString() {
|
||||
assertEquals("3, 5, 8", fibonacci().withIndex().filter { it.index > 3 }.take(3).joinToString { it.value.toString() })
|
||||
}
|
||||
|
||||
@Test fun withIndex() {
|
||||
val data = sequenceOf("foo", "bar")
|
||||
val indexed = data.withIndex().map { it.value.substring(0..it.index) }.toList()
|
||||
assertEquals(listOf("f", "ba"), indexed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onEach() {
|
||||
var count = 0
|
||||
val data = sequenceOf("foo", "bar")
|
||||
val newData = data.onEach { count += it.length }
|
||||
assertFalse(data === newData)
|
||||
assertEquals(0, count, "onEach should be executed lazily")
|
||||
|
||||
data.forEach { }
|
||||
assertEquals(0, count, "onEach should be executed only when resulting sequence is iterated")
|
||||
|
||||
val sum = newData.sumBy { it.length }
|
||||
assertEquals(sum, count)
|
||||
}
|
||||
|
||||
|
||||
@Test fun filterAndTakeWhileExtractTheElementsWithinRange() {
|
||||
assertEquals(listOf(144, 233, 377, 610, 987), fibonacci().filter { it > 100 }.takeWhile { it < 1000 }.toList())
|
||||
}
|
||||
|
||||
@Test fun foldReducesTheFirstNElements() {
|
||||
val sum = { a: Int, b: Int -> a + b }
|
||||
assertEquals(listOf(13, 21, 34, 55, 89).fold(0, sum), fibonacci().filter { it > 10 }.take(5).fold(0, sum))
|
||||
}
|
||||
|
||||
@Test fun takeExtractsTheFirstNElements() {
|
||||
assertEquals(listOf(0, 1, 1, 2, 3, 5, 8, 13, 21, 34), fibonacci().take(10).toList())
|
||||
}
|
||||
|
||||
@Test fun mapAndTakeWhileExtractTheTransformedElements() {
|
||||
assertEquals(listOf(0, 3, 3, 6, 9, 15), fibonacci().map { it * 3 }.takeWhile { i: Int -> i < 20 }.toList())
|
||||
}
|
||||
|
||||
@Test fun joinConcatenatesTheFirstNElementsAboveAThreshold() {
|
||||
assertEquals("13, 21, 34, 55, 89, ...", fibonacci().filter { it > 10 }.joinToString(separator = ", ", limit = 5))
|
||||
}
|
||||
|
||||
@Test fun drop() {
|
||||
assertEquals(emptyList(), emptySequence<Int>().drop(1).toList())
|
||||
listOf(2, 3, 4, 5).let { assertEquals(it, it.asSequence().drop(0).toList()) }
|
||||
assertEquals("13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ...", fibonacci().drop(7).joinToString(limit = 10))
|
||||
assertEquals("13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ...", fibonacci().drop(3).drop(4).joinToString(limit = 10))
|
||||
assertFailsWith<IllegalArgumentException> { fibonacci().drop(-1) }
|
||||
}
|
||||
|
||||
@Test fun take() {
|
||||
assertEquals(emptyList(), emptySequence<Int>().take(1).toList())
|
||||
assertEquals(emptyList(), fibonacci().take(0).toList())
|
||||
|
||||
assertEquals("0, 1, 1, 2, 3, 5, 8", fibonacci().take(7).joinToString())
|
||||
assertEquals("0, 1, 1, 2", fibonacci().take(7).take(4).joinToString())
|
||||
assertEquals("0, 1, 1, 2", fibonacci().take(4).take(5).joinToString())
|
||||
|
||||
assertEquals(emptyList(), fibonacci().take(1).drop(1).toList())
|
||||
assertEquals(emptyList(), fibonacci().take(1).drop(2).toList())
|
||||
|
||||
assertFailsWith<IllegalArgumentException> { fibonacci().take(-1) }
|
||||
}
|
||||
|
||||
@Test fun subSequence() {
|
||||
assertEquals(listOf(2, 3, 5, 8), fibonacci().drop(3).take(4).toList())
|
||||
assertEquals(listOf(2, 3, 5, 8), fibonacci().take(7).drop(3).toList())
|
||||
|
||||
val seq = fibonacci().drop(3).take(4)
|
||||
|
||||
assertEquals(listOf(2, 3, 5, 8), seq.take(5).toList())
|
||||
assertEquals(listOf(2, 3, 5), seq.take(3).toList())
|
||||
|
||||
assertEquals(emptyList(), seq.drop(5).toList())
|
||||
assertEquals(listOf(8), seq.drop(3).toList())
|
||||
|
||||
}
|
||||
|
||||
@Test fun dropWhile() {
|
||||
assertEquals("233, 377, 610", fibonacci().dropWhile { it < 200 }.take(3).joinToString(limit = 10))
|
||||
assertEquals("", sequenceOf(1).dropWhile { it < 200 }.joinToString(limit = 10))
|
||||
}
|
||||
|
||||
@Test fun zipWithNext() {
|
||||
val deltas = fibonacci().zipWithNext { a: Int, b: Int -> b - a }
|
||||
// deltas of 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...
|
||||
// is the same sequence prepended by 1
|
||||
assertEquals(listOf(1) + fibonacci().take(9), deltas.take(10).toList())
|
||||
|
||||
ensureIsIntermediate(source = sequenceOf(1, 2)) { it.zipWithNext { a: Int, b: Int -> b - a } }
|
||||
}
|
||||
|
||||
@Test fun zipWithNextPairs() {
|
||||
val pairs: Sequence<Pair<String, String>> = sequenceOf("a", "b", "c", "d").zipWithNext()
|
||||
assertEquals(listOf("a" to "b", "b" to "c", "c" to "d"), pairs.toList())
|
||||
|
||||
assertTrue(emptySequence<String>().zipWithNext().toList().isEmpty())
|
||||
assertTrue(sequenceOf(1).zipWithNext().toList().isEmpty())
|
||||
|
||||
ensureIsIntermediate(source = sequenceOf(1, 2)) { it.zipWithNext() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun chunked() {
|
||||
val infiniteSeq = generateSequence(0) { it + 1 }
|
||||
val result = infiniteSeq.chunked(4)
|
||||
assertEquals(listOf(
|
||||
listOf(0, 1, 2, 3),
|
||||
listOf(4, 5, 6, 7)
|
||||
), result.take(2).toList())
|
||||
|
||||
val size = 7
|
||||
val seq = infiniteSeq.take(7)
|
||||
|
||||
val result2 = seq.chunked(3) { it.joinToString("") }
|
||||
assertEquals(listOf("012", "345", "6"), result2.toList())
|
||||
|
||||
seq.toList().let { expectedSingleChunk ->
|
||||
assertEquals(expectedSingleChunk, seq.chunked(size).single())
|
||||
assertEquals(expectedSingleChunk, seq.chunked(size + 3).single())
|
||||
}
|
||||
|
||||
assertTrue(emptySequence<String>().chunked(3).none())
|
||||
|
||||
for (illegalValue in listOf(Int.MIN_VALUE, -1, 0)) {
|
||||
assertFailsWith<IllegalArgumentException>("size $illegalValue") { infiniteSeq.chunked(illegalValue) }
|
||||
}
|
||||
|
||||
ensureIsIntermediate(source = sequenceOf(1, 2, 3)) { it.chunked(2) }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun windowed() {
|
||||
val infiniteSeq = generateSequence(0) { it + 1 }
|
||||
val result = infiniteSeq.windowed(5, 3)
|
||||
result.take(10).forEachIndexed { windowIndex, window ->
|
||||
val startElement = windowIndex * 3
|
||||
assertEquals((startElement until startElement + 5).toList(), window)
|
||||
}
|
||||
|
||||
val size = 7
|
||||
val seq = infiniteSeq.take(7)
|
||||
|
||||
val result1 = seq.windowed(4, 2)
|
||||
assertEquals(listOf(
|
||||
listOf(0, 1, 2, 3),
|
||||
listOf(2, 3, 4, 5)
|
||||
), result1.toList())
|
||||
|
||||
val result1partial = seq.windowed(4, 2, partialWindows = true)
|
||||
assertEquals(listOf(
|
||||
listOf(0, 1, 2, 3),
|
||||
listOf(2, 3, 4, 5),
|
||||
listOf(4, 5, 6),
|
||||
listOf(6)
|
||||
), result1partial.toList())
|
||||
|
||||
val result2 = seq.windowed(2, 3) { it.joinToString("") }
|
||||
assertEquals(listOf("01", "34"), result2.toList())
|
||||
|
||||
val result2partial = seq.windowed(2, 3, partialWindows = true) { it.joinToString("") }
|
||||
assertEquals(listOf("01", "34", "6"), result2partial.toList())
|
||||
|
||||
assertEquals(seq.chunked(2).toList(), seq.windowed(2, 2, partialWindows = true).toList())
|
||||
|
||||
assertEquals(seq.take(2).toList(), seq.windowed(2, size).single())
|
||||
assertEquals(seq.take(3).toList(), seq.windowed(3, size + 3).single())
|
||||
|
||||
|
||||
assertEquals(seq.toList(), seq.windowed(size, 1).single())
|
||||
assertTrue(seq.windowed(size + 1, 1).none())
|
||||
|
||||
val result3partial = seq.windowed(size, 1, partialWindows = true)
|
||||
result3partial.forEachIndexed { index, window ->
|
||||
assertEquals(size - index, window.size, "size of window#$index")
|
||||
}
|
||||
|
||||
assertTrue(emptySequence<String>().windowed(3, 2).none())
|
||||
|
||||
for (illegalValue in listOf(Int.MIN_VALUE, -1, 0)) {
|
||||
assertFailsWith<IllegalArgumentException>("size $illegalValue") { seq.windowed(illegalValue, 1) }
|
||||
assertFailsWith<IllegalArgumentException>("step $illegalValue") { seq.windowed(1, illegalValue) }
|
||||
}
|
||||
|
||||
ensureIsIntermediate(source = sequenceOf(1, 2, 3)) { it.windowed(2, 1) }
|
||||
}
|
||||
|
||||
@Test fun zip() {
|
||||
expect(listOf("ab", "bc", "cd")) {
|
||||
sequenceOf("a", "b", "c").zip(sequenceOf("b", "c", "d")) { a, b -> a + b }.toList()
|
||||
}
|
||||
}
|
||||
|
||||
// @Test fun zipPairs() {
|
||||
// val pairStr = (fibonacci() zip fibonacci().map { i -> i*2 }).joinToString(limit = 10)
|
||||
// assertEquals("(0, 0), (1, 2), (1, 2), (2, 4), (3, 6), (5, 10), (8, 16), (13, 26), (21, 42), (34, 68), ...", pairStr)
|
||||
// }
|
||||
|
||||
@Test fun toStringJoinsNoMoreThanTheFirstTenElements() {
|
||||
assertEquals("0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...", fibonacci().joinToString(limit = 10))
|
||||
assertEquals("13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ...", fibonacci().filter { it > 10 }.joinToString(limit = 10))
|
||||
assertEquals("144, 233, 377, 610, 987", fibonacci().filter { it > 100 }.takeWhile { it < 1000 }.joinToString())
|
||||
}
|
||||
|
||||
|
||||
fun testPlus(doPlus: (Sequence<String>) -> Sequence<String>) {
|
||||
val seq = sequenceOf("foo", "bar")
|
||||
val seq2: Sequence<String> = doPlus(seq)
|
||||
assertEquals(listOf("foo", "bar"), seq.toList())
|
||||
assertEquals(listOf("foo", "bar", "cheese", "wine"), seq2.toList())
|
||||
}
|
||||
|
||||
|
||||
@Test fun plusElement() = testPlus { it + "cheese" + "wine" }
|
||||
@Test fun plusCollection() = testPlus { it + listOf("cheese", "wine") }
|
||||
@Test fun plusArray() = testPlus { it + arrayOf("cheese", "wine") }
|
||||
@Test fun plusSequence() = testPlus { it + sequenceOf("cheese", "wine") }
|
||||
|
||||
@Test fun plusAssign() {
|
||||
// lets use a mutable variable
|
||||
var seq = sequenceOf("a")
|
||||
seq += "foo"
|
||||
seq += listOf("beer")
|
||||
seq += arrayOf("cheese", "wine")
|
||||
seq += sequenceOf("bar", "foo")
|
||||
assertEquals(listOf("a", "foo", "beer", "cheese", "wine", "bar", "foo"), seq.toList())
|
||||
}
|
||||
|
||||
private fun testMinus(expected: List<String>? = null, doMinus: (Sequence<String>) -> Sequence<String>) {
|
||||
val a = sequenceOf("foo", "bar", "bar")
|
||||
val b: Sequence<String> = doMinus(a)
|
||||
val expected_ = expected ?: listOf("foo")
|
||||
assertEquals(expected_, b.toList())
|
||||
}
|
||||
|
||||
@Test fun minusElement() = testMinus(expected = listOf("foo", "bar")) { it - "bar" - "zoo" }
|
||||
@Test fun minusCollection() = testMinus { it - listOf("bar", "zoo") }
|
||||
@Test fun minusArray() = testMinus { it - arrayOf("bar", "zoo") }
|
||||
@Test fun minusSequence() = testMinus { it - sequenceOf("bar", "zoo") }
|
||||
|
||||
@Test fun minusIsLazyIterated() {
|
||||
val seq = sequenceOf("foo", "bar")
|
||||
val list = arrayListOf<String>()
|
||||
val result = seq - list
|
||||
|
||||
list += "foo"
|
||||
assertEquals(listOf("bar"), result.toList())
|
||||
list += "bar"
|
||||
assertEquals(emptyList<String>(), result.toList())
|
||||
}
|
||||
|
||||
@Test fun minusAssign() {
|
||||
// lets use a mutable variable of readonly list
|
||||
val data = sequenceOf("cheese", "foo", "beer", "cheese", "wine")
|
||||
var l = data
|
||||
l -= "cheese"
|
||||
assertEquals(listOf("foo", "beer", "cheese", "wine"), l.toList())
|
||||
l = data
|
||||
l -= listOf("cheese", "beer")
|
||||
assertEquals(listOf("foo", "wine"), l.toList())
|
||||
l -= arrayOf("wine", "bar")
|
||||
assertEquals(listOf("foo"), l.toList())
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test fun iterationOverSequence() {
|
||||
var s = ""
|
||||
for (i in sequenceOf(0, 1, 2, 3, 4, 5)) {
|
||||
s += i.toString()
|
||||
}
|
||||
assertEquals("012345", s)
|
||||
}
|
||||
|
||||
@Test fun sequenceFromFunction() {
|
||||
var count = 3
|
||||
|
||||
val sequence = generateSequence {
|
||||
count--
|
||||
if (count >= 0) count else null
|
||||
}
|
||||
|
||||
val list = sequence.toList()
|
||||
assertEquals(listOf(2, 1, 0), list)
|
||||
|
||||
assertFails {
|
||||
sequence.toList()
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun sequenceFromFunctionWithInitialValue() {
|
||||
val values = generateSequence(3) { n -> if (n > 0) n - 1 else null }
|
||||
val expected = listOf(3, 2, 1, 0)
|
||||
assertEquals(expected, values.toList())
|
||||
assertEquals(expected, values.toList(), "Iterating sequence second time yields the same result")
|
||||
}
|
||||
|
||||
@Test fun sequenceFromFunctionWithLazyInitialValue() {
|
||||
var start = 3
|
||||
val values = generateSequence({ start }, { n -> if (n > 0) n - 1 else null })
|
||||
val expected = listOf(3, 2, 1, 0)
|
||||
assertEquals(expected, values.toList())
|
||||
assertEquals(expected, values.toList(), "Iterating sequence second time yields the same result")
|
||||
|
||||
start = 2
|
||||
assertEquals(expected.drop(1), values.toList(), "Initial value function is called on each iterator request")
|
||||
|
||||
// does not throw on construction
|
||||
val errorValues = generateSequence<Int>({ (throw IllegalStateException()) }, { null })
|
||||
// does not throw on iteration
|
||||
val iterator = errorValues.iterator()
|
||||
// throws on advancing
|
||||
assertFails { iterator.next() }
|
||||
}
|
||||
|
||||
|
||||
@Test fun sequenceFromIterator() {
|
||||
val list = listOf(3, 2, 1, 0)
|
||||
val iterator = list.iterator()
|
||||
val sequence = iterator.asSequence()
|
||||
assertEquals(list, sequence.toList())
|
||||
assertFails {
|
||||
sequence.toList()
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun makeSequenceOneTimeConstrained() {
|
||||
val sequence = sequenceOf(1, 2, 3, 4)
|
||||
sequence.toList()
|
||||
sequence.toList()
|
||||
|
||||
val oneTime = sequence.constrainOnce()
|
||||
oneTime.toList()
|
||||
assertTrue("should fail with IllegalStateException") {
|
||||
assertFails {
|
||||
oneTime.toList()
|
||||
} is IllegalStateException
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun <T, C : MutableCollection<in T>> Sequence<T>.takeWhileTo(result: C, predicate: (T) -> Boolean): C {
|
||||
for (element in this) if (predicate(element)) result.add(element) else break
|
||||
return result
|
||||
}
|
||||
|
||||
@Test fun sequenceExtensions() {
|
||||
val d = ArrayList<Int>()
|
||||
sequenceOf(0, 1, 2, 3, 4, 5).takeWhileTo(d, { i -> i < 4 })
|
||||
assertEquals(4, d.size)
|
||||
}
|
||||
|
||||
@Test fun flatMapAndTakeExtractTheTransformedElements() {
|
||||
val expected = listOf(
|
||||
'3', // fibonacci(4) = 3
|
||||
'5', // fibonacci(5) = 5
|
||||
'8', // fibonacci(6) = 8
|
||||
'1', '3', // fibonacci(7) = 13
|
||||
'2', '1', // fibonacci(8) = 21
|
||||
'3', '4', // fibonacci(9) = 34
|
||||
'5' // fibonacci(10) = 55
|
||||
)
|
||||
|
||||
assertEquals(expected, fibonacci().drop(4).flatMap { it.toString().asSequence() }.take(10).toList())
|
||||
}
|
||||
|
||||
@Test fun flatMap() {
|
||||
val result = sequenceOf(1, 2).flatMap { (0..it).asSequence() }
|
||||
assertEquals(listOf(0, 1, 0, 1, 2), result.toList())
|
||||
}
|
||||
|
||||
@Test fun flatMapOnEmpty() {
|
||||
val result = sequenceOf<Int>().flatMap { (0..it).asSequence() }
|
||||
assertTrue(result.none())
|
||||
}
|
||||
|
||||
@Test fun flatMapWithEmptyItems() {
|
||||
val result = sequenceOf(1, 2, 4).flatMap { if (it == 2) sequenceOf<Int>() else (it - 1..it).asSequence() }
|
||||
assertEquals(listOf(0, 1, 3, 4), result.toList())
|
||||
}
|
||||
|
||||
@Test fun flatten() {
|
||||
val expected = listOf(0, 1, 0, 1, 2)
|
||||
|
||||
val seq = sequenceOf((0..1).asSequence(), (0..2).asSequence()).flatten()
|
||||
assertEquals(expected, seq.toList())
|
||||
|
||||
val seqMappedSeq = sequenceOf(1, 2).map { (0..it).asSequence() }.flatten()
|
||||
assertEquals(expected, seqMappedSeq.toList())
|
||||
|
||||
val seqOfIterable = sequenceOf(0..1, 0..2).flatten()
|
||||
assertEquals(expected, seqOfIterable.toList())
|
||||
|
||||
val seqMappedIterable = sequenceOf(1, 2).map { 0..it }.flatten()
|
||||
assertEquals(expected, seqMappedIterable.toList())
|
||||
}
|
||||
|
||||
@Test fun distinct() {
|
||||
val sequence = fibonacci().dropWhile { it < 10 }.take(20)
|
||||
assertEquals(listOf(1, 2, 3, 0), sequence.map { it % 4 }.distinct().toList())
|
||||
}
|
||||
|
||||
@Test fun distinctBy() {
|
||||
val sequence = fibonacci().dropWhile { it < 10 }.take(20)
|
||||
assertEquals(listOf(13, 34, 55, 144), sequence.distinctBy { it % 4 }.toList())
|
||||
}
|
||||
|
||||
@Test fun unzip() {
|
||||
val seq = sequenceOf(1 to 'a', 2 to 'b', 3 to 'c')
|
||||
val (ints, chars) = seq.unzip()
|
||||
assertEquals(listOf(1, 2, 3), ints)
|
||||
assertEquals(listOf('a', 'b', 'c'), chars)
|
||||
}
|
||||
|
||||
@Test fun sorted() {
|
||||
sequenceOf(3, 7, 5).let {
|
||||
it.sorted().iterator().assertSorted { a, b -> a <= b }
|
||||
it.sortedDescending().iterator().assertSorted { a, b -> a >= b }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun sortedBy() {
|
||||
sequenceOf("it", "greater", "less").let {
|
||||
it.sortedBy { it.length }.iterator().assertSorted { a, b -> compareValuesBy(a, b) { it.length } <= 0 }
|
||||
it.sortedByDescending { it.length }.iterator().assertSorted { a, b -> compareValuesBy(a, b) { it.length } >= 0 }
|
||||
}
|
||||
|
||||
sequenceOf('a', 'd', 'c', null).let {
|
||||
it.sortedBy {it}.iterator().assertSorted { a, b -> compareValues(a, b) <= 0 }
|
||||
it.sortedByDescending {it}.iterator().assertSorted { a, b -> compareValues(a, b) >= 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun sortedWith() {
|
||||
val comparator = compareBy { s: String -> s.reversed() }
|
||||
assertEquals(listOf("act", "wast", "test"), sequenceOf("act", "test", "wast").sortedWith(comparator).toList())
|
||||
}
|
||||
|
||||
/*
|
||||
test fun pairIterator() {
|
||||
val pairStr = (fibonacci() zip fibonacci().map { i -> i*2 }).joinToString(limit = 10)
|
||||
assertEquals("(0, 0), (1, 2), (1, 2), (2, 4), (3, 6), (5, 10), (8, 16), (13, 26), (21, 42), (34, 68), ...", pairStr)
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package test.collections
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class SetOperationsTest {
|
||||
@Test fun distinct() {
|
||||
assertEquals(listOf(1, 3, 5), listOf(1, 3, 3, 1, 5, 1, 3).distinct())
|
||||
assertTrue(listOf<Int>().distinct().isEmpty())
|
||||
}
|
||||
|
||||
@Test fun distinctBy() {
|
||||
assertEquals(listOf("some", "cat", "do"), arrayOf("some", "case", "cat", "do", "dog", "it").distinctBy { it.length })
|
||||
assertTrue(charArrayOf().distinctBy { it }.isEmpty())
|
||||
}
|
||||
|
||||
@Test fun union() {
|
||||
assertEquals(listOf(1, 3, 5), listOf(1, 3).union(listOf(5)).toList())
|
||||
assertEquals(listOf(1), listOf<Int>().union(listOf(1)).toList())
|
||||
}
|
||||
|
||||
@Test fun subtract() {
|
||||
assertEquals(listOf(1, 3), listOf(1, 3).subtract(listOf(5)).toList())
|
||||
assertEquals(listOf(1, 3), listOf(1, 3, 5).subtract(listOf(5)).toList())
|
||||
assertTrue(listOf(1, 3, 5).subtract(listOf(1, 3, 5)).none())
|
||||
assertTrue(listOf<Int>().subtract(listOf(1)).none())
|
||||
}
|
||||
|
||||
@Test fun intersect() {
|
||||
assertTrue(listOf(1, 3).intersect(listOf(5)).none())
|
||||
assertEquals(listOf(5), listOf(1, 3, 5).intersect(listOf(5)).toList())
|
||||
assertEquals(listOf(1, 3, 5), listOf(1, 3, 5).intersect(listOf(1, 3, 5)).toList())
|
||||
assertTrue(listOf<Int>().intersect(listOf(1)).none())
|
||||
}
|
||||
|
||||
fun testPlus(doPlus: (Set<String>) -> Set<String>) {
|
||||
val set = setOf("foo", "bar")
|
||||
val set2: Set<String> = doPlus(set)
|
||||
assertEquals(setOf("foo", "bar"), set)
|
||||
assertEquals(setOf("foo", "bar", "cheese", "wine"), set2)
|
||||
}
|
||||
|
||||
@Test fun plusElement() = testPlus { it + "bar" + "cheese" + "wine" }
|
||||
@Test fun plusCollection() = testPlus { it + listOf("bar", "cheese", "wine") }
|
||||
@Test fun plusArray() = testPlus { it + arrayOf("bar", "cheese", "wine") }
|
||||
@Test fun plusSequence() = testPlus { it + sequenceOf("bar", "cheese", "wine") }
|
||||
|
||||
@Test fun plusAssign() {
|
||||
// lets use a mutable variable
|
||||
var set = setOf("a")
|
||||
val setOriginal = set
|
||||
set += "foo"
|
||||
set += listOf("beer", "a")
|
||||
set += arrayOf("cheese", "beer")
|
||||
set += sequenceOf("bar", "foo")
|
||||
assertEquals(setOf("a", "foo", "beer", "cheese", "bar"), set)
|
||||
assertTrue(set !== setOriginal)
|
||||
|
||||
val mset = mutableSetOf("a")
|
||||
mset += "foo"
|
||||
mset += listOf("beer", "a")
|
||||
mset += arrayOf("cheese", "beer")
|
||||
mset += sequenceOf("bar", "foo")
|
||||
assertEquals(set, mset)
|
||||
}
|
||||
|
||||
private fun testMinus(doMinus: (Set<String>) -> Set<String>) {
|
||||
val a = setOf("foo", "bar")
|
||||
val b: Set<String> = doMinus(a)
|
||||
assertEquals(setOf("foo"), b)
|
||||
}
|
||||
|
||||
@Test fun minusElement() = testMinus { it - "bar" - "zoo" }
|
||||
@Test fun minusCollection() = testMinus { it - listOf("bar", "zoo") }
|
||||
@Test fun minusArray() = testMinus { it - arrayOf("bar", "zoo") }
|
||||
@Test fun minusSequence() = testMinus { it - sequenceOf("bar", "zoo") }
|
||||
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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 test.coroutines
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
|
||||
class CoroutineContextTest {
|
||||
data class CtxA(val i: Int) : AbstractCoroutineContextElement(CtxA) {
|
||||
companion object Key : CoroutineContext.Key<CtxA>
|
||||
}
|
||||
|
||||
data class CtxB(val i: Int) : AbstractCoroutineContextElement(CtxB) {
|
||||
companion object Key : CoroutineContext.Key<CtxB>
|
||||
}
|
||||
|
||||
data class CtxC(val i: Int) : AbstractCoroutineContextElement(CtxC) {
|
||||
companion object Key : CoroutineContext.Key<CtxC>
|
||||
}
|
||||
|
||||
object Disp1 : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
|
||||
override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> = continuation
|
||||
override fun toString(): String = "Disp1"
|
||||
}
|
||||
|
||||
object Disp2 : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
|
||||
override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> = continuation
|
||||
override fun toString(): String = "Disp2"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetPlusFold() {
|
||||
var ctx: CoroutineContext = EmptyCoroutineContext
|
||||
assertContents(ctx)
|
||||
assertEquals("EmptyCoroutineContext", ctx.toString())
|
||||
|
||||
ctx += CtxA(1)
|
||||
assertContents(ctx, CtxA(1))
|
||||
assertEquals("CtxA(i=1)", ctx.toString())
|
||||
assertEquals(CtxA(1), ctx[CtxA])
|
||||
assertEquals(null, ctx[CtxB])
|
||||
assertEquals(null, ctx[CtxC])
|
||||
|
||||
ctx += CtxB(2)
|
||||
assertContents(ctx, CtxA(1), CtxB(2))
|
||||
assertEquals("[CtxA(i=1), CtxB(i=2)]", ctx.toString())
|
||||
assertEquals(CtxA(1), ctx[CtxA])
|
||||
assertEquals(CtxB(2), ctx[CtxB])
|
||||
assertEquals(null, ctx[CtxC])
|
||||
|
||||
ctx += CtxC(3)
|
||||
assertContents(ctx, CtxA(1), CtxB(2), CtxC(3))
|
||||
assertEquals("[CtxA(i=1), CtxB(i=2), CtxC(i=3)]", ctx.toString())
|
||||
assertEquals(CtxA(1), ctx[CtxA])
|
||||
assertEquals(CtxB(2), ctx[CtxB])
|
||||
assertEquals(CtxC(3), ctx[CtxC])
|
||||
|
||||
ctx += CtxB(4)
|
||||
assertContents(ctx, CtxA(1), CtxC(3), CtxB(4))
|
||||
assertEquals("[CtxA(i=1), CtxC(i=3), CtxB(i=4)]", ctx.toString())
|
||||
assertEquals(CtxA(1), ctx[CtxA])
|
||||
assertEquals(CtxB(4), ctx[CtxB])
|
||||
assertEquals(CtxC(3), ctx[CtxC])
|
||||
|
||||
ctx += CtxA(5)
|
||||
assertContents(ctx, CtxC(3), CtxB(4), CtxA(5))
|
||||
assertEquals("[CtxC(i=3), CtxB(i=4), CtxA(i=5)]", ctx.toString())
|
||||
assertEquals(CtxA(5), ctx[CtxA])
|
||||
assertEquals(CtxB(4), ctx[CtxB])
|
||||
assertEquals(CtxC(3), ctx[CtxC])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMinusKey() {
|
||||
var ctx: CoroutineContext = CtxA(1) + CtxB(2) + CtxC(3)
|
||||
assertContents(ctx, CtxA(1), CtxB(2), CtxC(3))
|
||||
assertEquals("[CtxA(i=1), CtxB(i=2), CtxC(i=3)]", ctx.toString())
|
||||
|
||||
ctx = ctx.minusKey(CtxA)
|
||||
assertContents(ctx, CtxB(2), CtxC(3))
|
||||
assertEquals("[CtxB(i=2), CtxC(i=3)]", ctx.toString())
|
||||
assertEquals(null, ctx[CtxA])
|
||||
assertEquals(CtxB(2), ctx[CtxB])
|
||||
assertEquals(CtxC(3), ctx[CtxC])
|
||||
|
||||
ctx = ctx.minusKey(CtxC)
|
||||
assertContents(ctx, CtxB(2))
|
||||
assertEquals("CtxB(i=2)", ctx.toString())
|
||||
assertEquals(null, ctx[CtxA])
|
||||
assertEquals(CtxB(2), ctx[CtxB])
|
||||
assertEquals(null, ctx[CtxC])
|
||||
|
||||
ctx = ctx.minusKey(CtxC)
|
||||
assertContents(ctx, CtxB(2))
|
||||
assertEquals("CtxB(i=2)", ctx.toString())
|
||||
assertEquals(null, ctx[CtxA])
|
||||
assertEquals(CtxB(2), ctx[CtxB])
|
||||
assertEquals(null, ctx[CtxC])
|
||||
|
||||
ctx = ctx.minusKey(CtxB)
|
||||
assertContents(ctx)
|
||||
assertEquals("EmptyCoroutineContext", ctx.toString())
|
||||
assertEquals(null, ctx[CtxA])
|
||||
assertEquals(null, ctx[CtxB])
|
||||
assertEquals(null, ctx[CtxC])
|
||||
|
||||
assertEquals(EmptyCoroutineContext, ctx)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPlusCombined() {
|
||||
val ctx1 = CtxA(1) + CtxB(2)
|
||||
val ctx2 = CtxB(3) + CtxC(4)
|
||||
val ctx = ctx1 + ctx2
|
||||
assertContents(ctx, CtxA(1), CtxB(3), CtxC(4))
|
||||
assertEquals("[CtxA(i=1), CtxB(i=3), CtxC(i=4)]", ctx.toString())
|
||||
assertEquals(CtxA(1), ctx[CtxA])
|
||||
assertEquals(CtxB(3), ctx[CtxB])
|
||||
assertEquals(CtxC(4), ctx[CtxC])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLastDispatcher() {
|
||||
var ctx: CoroutineContext = EmptyCoroutineContext
|
||||
assertContents(ctx)
|
||||
ctx += CtxA(1)
|
||||
assertContents(ctx, CtxA(1))
|
||||
ctx += Disp1
|
||||
assertContents(ctx, CtxA(1), Disp1)
|
||||
ctx += CtxA(2)
|
||||
assertContents(ctx, CtxA(2), Disp1)
|
||||
ctx += CtxB(3)
|
||||
assertContents(ctx, CtxA(2), CtxB(3), Disp1)
|
||||
ctx += Disp2
|
||||
assertContents(ctx, CtxA(2), CtxB(3), Disp2)
|
||||
ctx += (CtxB(4) + CtxC(5))
|
||||
assertContents(ctx, CtxA(2), CtxB(4), CtxC(5), Disp2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEquals() {
|
||||
val ctx1 = CtxA(1) + CtxB(2) + CtxC(3)
|
||||
val ctx2 = CtxB(2) + CtxC(3) + CtxA(1) // same
|
||||
val ctx3 = CtxC(3) + CtxA(1) + CtxB(2) // same
|
||||
val ctx4 = CtxA(1) + CtxB(2) + CtxC(4) // different
|
||||
assertEquals(ctx1, ctx2)
|
||||
assertEquals(ctx1, ctx3)
|
||||
assertEquals(ctx2, ctx3)
|
||||
assertNotEquals(ctx1, ctx4)
|
||||
assertNotEquals(ctx2, ctx4)
|
||||
assertNotEquals(ctx3, ctx4)
|
||||
}
|
||||
|
||||
private fun assertContents(ctx: CoroutineContext, vararg elements: CoroutineContext.Element) {
|
||||
val set = ctx.fold(setOf<CoroutineContext>()) { a, b -> a + b }
|
||||
assertEquals(listOf(*elements), set.toList())
|
||||
for (elem in elements)
|
||||
assertTrue(ctx[elem.key] == elem)
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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 test.coroutines
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
|
||||
/**
|
||||
* Test to ensure that coroutine machinery does not call equals/hashCode/toString anywhere.
|
||||
*/
|
||||
class CoroutinesReferenceValuesTest {
|
||||
class BadClass {
|
||||
override fun equals(other: Any?): Boolean = error("equals")
|
||||
override fun hashCode(): Int = error("hashCode")
|
||||
override fun toString(): String = error("toString")
|
||||
}
|
||||
|
||||
var counter = 0
|
||||
|
||||
// tail-suspend function via suspendCoroutine (test SafeContinuation)
|
||||
suspend fun getBadClassViaSuspend(): BadClass = suspendCoroutine { cont ->
|
||||
counter++
|
||||
cont.resume(BadClass())
|
||||
}
|
||||
|
||||
// state machine
|
||||
suspend fun checkBadClassTwice() {
|
||||
assertTrue(getBadClassViaSuspend() is BadClass)
|
||||
assertTrue(getBadClassViaSuspend() is BadClass)
|
||||
}
|
||||
|
||||
fun <T> suspend(block: suspend () -> T) = block
|
||||
|
||||
@Test
|
||||
fun testBadClass() {
|
||||
val bad = suspend {
|
||||
checkBadClassTwice()
|
||||
getBadClassViaSuspend()
|
||||
}
|
||||
var result: BadClass? = null
|
||||
bad.startCoroutine(object : Continuation<BadClass> {
|
||||
override val context: CoroutineContext = EmptyCoroutineContext
|
||||
|
||||
override fun resume(value: BadClass) {
|
||||
assertTrue(result == null)
|
||||
result = value
|
||||
}
|
||||
|
||||
override fun resumeWithException(exception: Throwable) {
|
||||
throw exception
|
||||
}
|
||||
})
|
||||
assertTrue(result is BadClass)
|
||||
assertEquals(3, counter)
|
||||
}
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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 test.coroutines
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.coroutines.experimental.buildSequence
|
||||
import kotlin.coroutines.experimental.buildIterator
|
||||
|
||||
class SequenceBuilderTest {
|
||||
@Test
|
||||
fun testSimple() {
|
||||
val result = buildSequence {
|
||||
for (i in 1..3) {
|
||||
yield(2 * i)
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(listOf(2, 4, 6), result.toList())
|
||||
// Repeated calls also work
|
||||
assertEquals(listOf(2, 4, 6), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCallHasNextSeveralTimes() {
|
||||
val result = buildSequence {
|
||||
yield(1)
|
||||
}
|
||||
|
||||
val iterator = result.iterator()
|
||||
|
||||
assertTrue(iterator.hasNext())
|
||||
assertTrue(iterator.hasNext())
|
||||
assertTrue(iterator.hasNext())
|
||||
|
||||
assertEquals(1, iterator.next())
|
||||
|
||||
assertFalse(iterator.hasNext())
|
||||
assertFalse(iterator.hasNext())
|
||||
assertFalse(iterator.hasNext())
|
||||
|
||||
assertFailsWith<NoSuchElementException> { iterator.next() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testManualIteration() {
|
||||
val result = buildSequence {
|
||||
yield(1)
|
||||
yield(2)
|
||||
yield(3)
|
||||
}
|
||||
|
||||
val iterator = result.iterator()
|
||||
|
||||
assertTrue(iterator.hasNext())
|
||||
assertTrue(iterator.hasNext())
|
||||
assertEquals(1, iterator.next())
|
||||
|
||||
assertTrue(iterator.hasNext())
|
||||
assertTrue(iterator.hasNext())
|
||||
assertEquals(2, iterator.next())
|
||||
|
||||
assertEquals(3, iterator.next())
|
||||
|
||||
assertFalse(iterator.hasNext())
|
||||
assertFalse(iterator.hasNext())
|
||||
|
||||
assertFailsWith<NoSuchElementException> { iterator.next() }
|
||||
|
||||
assertEquals(1, result.iterator().next())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEmptySequence() {
|
||||
val result = buildSequence<Int> {}
|
||||
val iterator = result.iterator()
|
||||
|
||||
assertFalse(iterator.hasNext())
|
||||
assertFalse(iterator.hasNext())
|
||||
|
||||
assertFailsWith<NoSuchElementException> { iterator.next() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLaziness() {
|
||||
var sharedVar = -2
|
||||
val result = buildSequence {
|
||||
while (true) {
|
||||
when (sharedVar) {
|
||||
-1 -> return@buildSequence
|
||||
-2 -> error("Invalid state: -2")
|
||||
else -> yield(sharedVar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val iterator = result.iterator()
|
||||
|
||||
sharedVar = 1
|
||||
assertTrue(iterator.hasNext())
|
||||
assertEquals(1, iterator.next())
|
||||
|
||||
sharedVar = 2
|
||||
assertTrue(iterator.hasNext())
|
||||
assertEquals(2, iterator.next())
|
||||
|
||||
sharedVar = 3
|
||||
assertTrue(iterator.hasNext())
|
||||
assertEquals(3, iterator.next())
|
||||
|
||||
sharedVar = -1
|
||||
assertFalse(iterator.hasNext())
|
||||
assertFailsWith<NoSuchElementException> { iterator.next() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExceptionInCoroutine() {
|
||||
var sharedVar = -2
|
||||
val result = buildSequence {
|
||||
while (true) {
|
||||
when (sharedVar) {
|
||||
-1 -> return@buildSequence
|
||||
-2 -> throw UnsupportedOperationException("-2 is unsupported")
|
||||
else -> yield(sharedVar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val iterator = result.iterator()
|
||||
|
||||
sharedVar = 1
|
||||
assertEquals(1, iterator.next())
|
||||
|
||||
sharedVar = -2
|
||||
assertFailsWith<UnsupportedOperationException> { iterator.hasNext() }
|
||||
assertFailsWith<IllegalStateException> { iterator.hasNext() }
|
||||
assertFailsWith<IllegalStateException> { iterator.next() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testParallelIteration() {
|
||||
var inc = 0
|
||||
val result = buildSequence {
|
||||
for (i in 1..3) {
|
||||
inc++
|
||||
yield(inc * i)
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(listOf(Pair(1, 2), Pair(6, 8), Pair(15, 18)), result.zip(result).toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllIterator() {
|
||||
val result = buildSequence {
|
||||
yieldAll(listOf(1, 2, 3).iterator())
|
||||
}
|
||||
assertEquals(listOf(1, 2, 3), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllSequence() {
|
||||
val result = buildSequence {
|
||||
yieldAll(sequenceOf(1, 2, 3))
|
||||
}
|
||||
assertEquals(listOf(1, 2, 3), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllCollection() {
|
||||
val result = buildSequence {
|
||||
yieldAll(listOf(1, 2, 3))
|
||||
}
|
||||
assertEquals(listOf(1, 2, 3), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllCollectionMixedFirst() {
|
||||
val result = buildSequence {
|
||||
yield(0)
|
||||
yieldAll(listOf(1, 2, 3))
|
||||
}
|
||||
assertEquals(listOf(0, 1, 2, 3), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllCollectionMixedLast() {
|
||||
val result = buildSequence {
|
||||
yieldAll(listOf(1, 2, 3))
|
||||
yield(4)
|
||||
}
|
||||
assertEquals(listOf(1, 2, 3, 4), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllCollectionMixedBoth() {
|
||||
val result = buildSequence {
|
||||
yield(0)
|
||||
yieldAll(listOf(1, 2, 3))
|
||||
yield(4)
|
||||
}
|
||||
assertEquals(listOf(0, 1, 2, 3, 4), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllCollectionMixedLong() {
|
||||
val result = buildSequence {
|
||||
yield(0)
|
||||
yieldAll(listOf(1, 2, 3))
|
||||
yield(4)
|
||||
yield(5)
|
||||
yieldAll(listOf(6))
|
||||
yield(7)
|
||||
yieldAll(listOf())
|
||||
yield(8)
|
||||
}
|
||||
assertEquals(listOf(0, 1, 2, 3, 4, 5, 6, 7, 8), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllCollectionOneEmpty() {
|
||||
val result = buildSequence<Int> {
|
||||
yieldAll(listOf())
|
||||
}
|
||||
assertEquals(listOf(), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllCollectionManyEmpty() {
|
||||
val result = buildSequence<Int> {
|
||||
yieldAll(listOf())
|
||||
yieldAll(listOf())
|
||||
yieldAll(listOf())
|
||||
}
|
||||
assertEquals(listOf(), result.toList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testYieldAllSideEffects() {
|
||||
val effects = arrayListOf<Any>()
|
||||
val result = buildSequence {
|
||||
effects.add("a")
|
||||
yieldAll(listOf(1, 2))
|
||||
effects.add("b")
|
||||
yieldAll(listOf())
|
||||
effects.add("c")
|
||||
yieldAll(listOf(3))
|
||||
effects.add("d")
|
||||
yield(4)
|
||||
effects.add("e")
|
||||
yieldAll(listOf())
|
||||
effects.add("f")
|
||||
yield(5)
|
||||
}
|
||||
|
||||
for (res in result) {
|
||||
effects.add("(") // marks step start
|
||||
effects.add(res)
|
||||
effects.add(")") // marks step end
|
||||
}
|
||||
assertEquals(
|
||||
listOf(
|
||||
"a",
|
||||
"(", 1, ")",
|
||||
"(", 2, ")",
|
||||
"b", "c",
|
||||
"(", 3, ")",
|
||||
"d",
|
||||
"(", 4, ")",
|
||||
"e", "f",
|
||||
"(", 5, ")"
|
||||
),
|
||||
effects.toList()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInfiniteYieldAll() {
|
||||
val values = buildIterator {
|
||||
while (true) {
|
||||
yieldAll((1..5).map { it })
|
||||
}
|
||||
}
|
||||
|
||||
var sum = 0
|
||||
repeat(10) {
|
||||
sum += values.next() //.also(::println)
|
||||
}
|
||||
assertEquals(30, sum)
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package test.language
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class EscapedTestNamesTest {
|
||||
|
||||
@Test fun `strings equal`() {
|
||||
val actual = "abc"
|
||||
assertEquals("abc", actual)
|
||||
}
|
||||
|
||||
@Test fun `numbers equal`() {
|
||||
val actual = 5
|
||||
assertEquals(5, actual)
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package test.numbers
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
// TODO: Run these tests during compiler test only (JVM & JS)
|
||||
class BitwiseOperationsTest {
|
||||
@Test fun orForInt() {
|
||||
assertEquals(3, 2 or 1)
|
||||
}
|
||||
|
||||
@Test fun andForInt() {
|
||||
assertEquals(0, 1 and 0)
|
||||
}
|
||||
|
||||
@Test fun xorForInt() {
|
||||
assertEquals(1, 2 xor 3)
|
||||
}
|
||||
|
||||
@Test fun shlForInt() {
|
||||
assertEquals(4, 1 shl 2)
|
||||
}
|
||||
|
||||
@Test fun shrForInt() {
|
||||
assertEquals(1, 2 shr 1)
|
||||
}
|
||||
|
||||
@Test fun ushrForInt() {
|
||||
assertEquals(2147483647, -1 ushr 1)
|
||||
}
|
||||
|
||||
@Test fun invForInt() {
|
||||
assertEquals(0, (-1).inv())
|
||||
}
|
||||
}
|
||||
@@ -1,824 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 test.numbers.harmony_math
|
||||
|
||||
import kotlin.math.*
|
||||
import kotlin.test.*
|
||||
|
||||
class HarmonyMath {
|
||||
|
||||
fun assertEquals(expected: Double, actual: Double, tolerance: Double? = null) =
|
||||
assertEquals(null, expected, actual, tolerance)
|
||||
|
||||
fun assertEquals(expected: Float, actual: Float, tolerance: Float? = null) =
|
||||
assertEquals(null, expected, actual, tolerance)
|
||||
|
||||
fun Double.Companion.isNaN(v: Double) = v.isNaN()
|
||||
fun Float.Companion.isNaN(v: Float) = v.isNaN()
|
||||
|
||||
fun pow(a: Double, b: Double) = a.pow(b)
|
||||
fun pow(a: Float, b: Float) = a.pow(b)
|
||||
|
||||
fun ulp(v: Double) = v.ulp
|
||||
fun ulp(v: Float) = v.ulp
|
||||
|
||||
fun assertEquals(message: String?, expected: Int, actual: Int) = assertEquals(expected, actual, message)
|
||||
fun assertEquals(message: String?, expected: Long, actual: Long) = assertEquals(expected, actual, message)
|
||||
|
||||
fun assertEquals(message: String?, expected: Double, actual: Double, tolerance: Double? = null) {
|
||||
val tolerance_ = tolerance?.let { abs(it) } ?: 0.000000000001
|
||||
if (abs(expected - actual) > tolerance_) {
|
||||
assertEquals(expected, actual, message)
|
||||
}
|
||||
}
|
||||
|
||||
fun assertEquals(message: String?, expected: Float, actual: Float, tolerance: Float? = null) {
|
||||
val tolerance_ = tolerance?.let { abs(it) } ?: 0.0000001f
|
||||
if (abs(expected - actual) > tolerance_) {
|
||||
assertEquals(expected, actual, message)
|
||||
}
|
||||
}
|
||||
|
||||
fun assertTrue(message: String? = null, condition: Boolean) = assertTrue(condition, message)
|
||||
|
||||
internal var HYP = sqrt(2.0)
|
||||
|
||||
internal var OPP = 1.0
|
||||
|
||||
internal var ADJ = 1.0
|
||||
|
||||
/* Required to make previous preprocessor flags work - do not remove */
|
||||
internal var unused = 0
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.abs(Double)
|
||||
*/
|
||||
@Test fun absD() {
|
||||
// Test for abs(Double): Double
|
||||
|
||||
assertTrue("Incorrect Double abs value",
|
||||
abs(-1908.8976) == 1908.8976)
|
||||
assertTrue("Incorrect Double abs value",
|
||||
abs(1908.8976) == 1908.8976)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.abs(float)
|
||||
*/
|
||||
@Test fun absF() {
|
||||
// Test for abs(float): float
|
||||
assertTrue("Incorrect float abs value",
|
||||
abs(-1908.8976f) == 1908.8976f)
|
||||
assertTrue("Incorrect float abs value",
|
||||
abs(1908.8976f) == 1908.8976f)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.abs(int)
|
||||
*/
|
||||
@Test fun absI() {
|
||||
// Test for abs(int): int
|
||||
assertTrue("Incorrect int abs value", abs(-1908897) == 1908897)
|
||||
assertTrue("Incorrect int abs value", abs(1908897) == 1908897)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.abs(long)
|
||||
*/
|
||||
@Test fun absJ() {
|
||||
// Test for abs(long): long
|
||||
assertTrue("Incorrect long abs value",
|
||||
abs(-19088976000089L) == 19088976000089L)
|
||||
assertTrue("Incorrect long abs value",
|
||||
abs(19088976000089L) == 19088976000089L)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.acos(Double)
|
||||
*/
|
||||
@Test fun acosD() {
|
||||
// Test for acos(Double): Double
|
||||
val r = cos(acos(ADJ / HYP))
|
||||
val lr = r.toBits()
|
||||
val t = (ADJ / HYP).toBits()
|
||||
assertTrue("Returned incorrect arc cosine", lr == t || lr + 1 == t || lr - 1 == t)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.asin(Double)
|
||||
*/
|
||||
@Test fun asinD() {
|
||||
// Test for asin(Double): Double
|
||||
val r = sin(asin(OPP / HYP))
|
||||
val lr = r.toBits()
|
||||
val t = (OPP / HYP).toBits()
|
||||
assertTrue("Returned incorrect arc sine", lr == t || lr + 1 == t || lr - 1 == t)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.atan(Double)
|
||||
*/
|
||||
@Test fun atanD() {
|
||||
// Test for atan(Double): Double
|
||||
val answer = tan(atan(1.0))
|
||||
assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0 && answer >= 9.9999999999999983E-1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.atan2(Double, Double)
|
||||
*/
|
||||
@Test fun atan2DD() {
|
||||
// Test for atan2(Double, Double): Double
|
||||
val answer = atan(tan(1.0))
|
||||
assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0 && answer >= 9.9999999999999983E-1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.ceil(Double)
|
||||
*/
|
||||
@Test fun ceilD() {
|
||||
// Test for ceil(Double): Double
|
||||
assertEquals("Incorrect ceiling for Double",
|
||||
79.0, ceil(78.89), 0.0)
|
||||
assertEquals("Incorrect ceiling for Double",
|
||||
-78.0, ceil(-78.89), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.withSign(Double)
|
||||
*/
|
||||
@Test fun withSign_D() {
|
||||
for (i in COPYSIGN_DD_CASES.indices) {
|
||||
val magnitude = COPYSIGN_DD_CASES[i]
|
||||
val absMagnitudeBits = abs(magnitude).toBits()
|
||||
val negMagnitudeBits = (-abs(magnitude)).toBits()
|
||||
|
||||
assertTrue("The result should be NaN.", Double.isNaN(Double.NaN.withSign(magnitude)))
|
||||
|
||||
for (j in COPYSIGN_DD_CASES.indices) {
|
||||
val sign = COPYSIGN_DD_CASES[j]
|
||||
val resultBits = magnitude.withSign(sign).toBits()
|
||||
|
||||
if (sign > 0 || (+0.0).toBits() == sign.toBits() || 0.0.toBits() == sign.toBits()) {
|
||||
assertEquals(
|
||||
"If the sign is positive, the result should be positive.",
|
||||
absMagnitudeBits, resultBits)
|
||||
}
|
||||
if (sign < 0 || (-0.0).toBits() == sign.toBits()) {
|
||||
assertEquals(
|
||||
"If the sign is negative, the result should be negative.",
|
||||
negMagnitudeBits, resultBits)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("The result should be NaN.", Double.isNaN(Double.NaN.withSign(Double.NaN)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.withSign(Float)
|
||||
*/
|
||||
@Test fun withSign_F() {
|
||||
for (i in COPYSIGN_FF_CASES.indices) {
|
||||
val magnitude = COPYSIGN_FF_CASES[i]
|
||||
val absMagnitudeBits = abs(magnitude).toBits()
|
||||
val negMagnitudeBits = (-abs(magnitude)).toBits()
|
||||
|
||||
assertTrue("The result should be NaN.", Float.isNaN(Float.NaN.withSign(magnitude)))
|
||||
|
||||
for (j in COPYSIGN_FF_CASES.indices) {
|
||||
val sign = COPYSIGN_FF_CASES[j]
|
||||
val resultBits = magnitude.withSign(sign).toBits()
|
||||
if (sign > 0 || (+0.0f).toBits() == sign.toBits() || 0.0f.toBits() == sign.toBits()) {
|
||||
assertEquals(
|
||||
"If the sign is positive, the result should be positive.",
|
||||
absMagnitudeBits, resultBits)
|
||||
}
|
||||
if (sign < 0 || (-0.0f).toBits() == sign.toBits()) {
|
||||
assertEquals(
|
||||
"If the sign is negative, the result should be negative.",
|
||||
negMagnitudeBits, resultBits)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("The result should be NaN.", Float.isNaN(Float.NaN.withSign(Float.NaN)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.cos(Double)
|
||||
*/
|
||||
@Test fun cosD() {
|
||||
// Test for cos(Double): Double
|
||||
assertEquals("Incorrect answer", 1.0, cos(0.0), 0.0)
|
||||
assertEquals("Incorrect answer", 0.5403023058681398, cos(1.0), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.cosh(Double)
|
||||
*/
|
||||
@Test fun cosh_D() {
|
||||
// Test for special situations
|
||||
assertTrue(Double.isNaN(cosh(Double.NaN)))
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, cosh(Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, cosh(Double.NEGATIVE_INFINITY), 0.0)
|
||||
assertEquals("Should return 1.0", 1.0, cosh(+0.0), 0.0)
|
||||
assertEquals("Should return 1.0", 1.0, cosh(-0.0), 0.0)
|
||||
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, cosh(1234.56), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, cosh(-1234.56), 0.0)
|
||||
assertEquals("Should return 1.0000000000005", 1.0000000000005, cosh(0.000001), 0.0)
|
||||
assertEquals("Should return 1.0000000000005", 1.0000000000005, cosh(-0.000001), 0.0)
|
||||
assertEquals("Should return 5.212214351945598", 5.212214351945598, cosh(2.33482), 0.0)
|
||||
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, cosh(Double.MAX_VALUE), 0.0)
|
||||
assertEquals("Should return 1.0", 1.0, cosh(Double.MIN_VALUE), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.exp(Double)
|
||||
*/
|
||||
@Test fun expD() {
|
||||
// Test for exp(Double): Double
|
||||
assertTrue("Incorrect answer returned for simple power", abs(exp(4.0) - E * E * E * E) < 0.1)
|
||||
assertTrue("Incorrect answer returned for larger power", ln(abs(exp(5.5)) - 5.5) < 10.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.expm1(Double)
|
||||
*/
|
||||
@Test fun expm1_D() {
|
||||
// Test for special cases
|
||||
assertTrue("Should return NaN", Double.isNaN(expm1(Double.NaN)))
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, expm1(Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals("Should return -1.0", -1.0, expm1(Double.NEGATIVE_INFINITY), 0.0)
|
||||
|
||||
assertEquals(0.0.toBits(), expm1(0.0).toBits())
|
||||
assertEquals(+0.0.toBits(), expm1(+0.0).toBits())
|
||||
assertEquals((-0.0).toBits(), expm1(-0.0).toBits())
|
||||
|
||||
assertEquals("Should return -9.999950000166666E-6",
|
||||
-9.999950000166666E-6, expm1(-0.00001), 0.0)
|
||||
assertEquals("Should return 1.0145103074469635E60",
|
||||
1.0145103074469635E60, expm1(138.16951162), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, expm1(123456789123456789123456789.4521584223), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, expm1(Double.MAX_VALUE), 0.0)
|
||||
assertEquals("Should return MIN_VALUE", Double.MIN_VALUE, expm1(Double.MIN_VALUE), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.floor(Double)
|
||||
*/
|
||||
@Test fun floorD() {
|
||||
assertEquals("Incorrect floor for int", 42.0, floor(42.0), 0.0)
|
||||
assertEquals("Incorrect floor for -int", -2.0, floor(-2.0), 0.0)
|
||||
assertEquals("Incorrect floor for zero", 0.0, floor(0.0), 0.0)
|
||||
|
||||
assertEquals("Incorrect floor for +Double", 78.0, floor(78.89), 0.0)
|
||||
assertEquals("Incorrect floor for -Double", -79.0, floor(-78.89), 0.0)
|
||||
assertEquals("floor large +Double", 3.7314645675925406E19, floor(3.7314645675925406E19), 0.0)
|
||||
assertEquals("floor large -Double", -8.173521839218E12, floor(-8.173521839218E12), 0.0)
|
||||
assertEquals("floor small Double", 0.0, floor(1.11895241315E-102), 0.0)
|
||||
|
||||
// Compare toString representations here since -0.0 = +0.0, and
|
||||
// NaN != NaN and we need to distinguish
|
||||
|
||||
assertEquals(Double.NaN.toString(), floor(Double.NaN).toString(), "Floor failed for NaN")
|
||||
assertEquals((+0.0).toString(), floor(+0.0).toString(), "Floor failed for +0.0")
|
||||
assertEquals((-0.0).toString(), floor(-0.0).toString(), "Floor failed for -0.0")
|
||||
assertEquals(Double.POSITIVE_INFINITY.toString(), floor(Double.POSITIVE_INFINITY).toString(),
|
||||
"Floor failed for +infinity")
|
||||
assertEquals(Double.NEGATIVE_INFINITY.toString(), floor(Double.NEGATIVE_INFINITY).toString(),
|
||||
"Floor failed for -infinity")
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.hypot(Double, Double)
|
||||
*/
|
||||
@Test fun hypot_DD() {
|
||||
// Test for special cases
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, hypot(Double.POSITIVE_INFINITY,
|
||||
1.0), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY,
|
||||
123.324), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, hypot(-758.2587,
|
||||
Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, hypot(5687.21,
|
||||
Double.NEGATIVE_INFINITY), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, hypot(Double.POSITIVE_INFINITY,
|
||||
Double.NEGATIVE_INFINITY), 0.0)
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY,
|
||||
Double.POSITIVE_INFINITY), 0.0)
|
||||
assertTrue("Should be NaN", Double.isNaN(hypot(Double.NaN,
|
||||
2342301.89843)))
|
||||
assertTrue("Should be NaN", Double.isNaN(hypot(-345.2680,
|
||||
Double.NaN)))
|
||||
|
||||
assertEquals("Should return 2396424.905416697", 2396424.905416697, hypot(12322.12, -2396393.2258), 0.0)
|
||||
assertEquals("Should return 138.16958070558556", 138.16958070558556,
|
||||
hypot(-138.16951162, 0.13817035864), 0.0)
|
||||
assertEquals("Should return 1.7976931348623157E308",
|
||||
1.7976931348623157E308, hypot(Double.MAX_VALUE, 211370.35), 0.0)
|
||||
assertEquals("Should return 5413.7185", 5413.7185, hypot(
|
||||
-5413.7185, Double.MIN_VALUE), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.IEEEremainder(Double, Double)
|
||||
*/
|
||||
@Test fun IEEEremainderDD() {
|
||||
// Test for IEEEremainder(Double, Double): Double
|
||||
assertEquals("Incorrect remainder returned",
|
||||
0.0, 1.0.IEEErem(1.0), 0.0)
|
||||
assertTrue("Incorrect remainder returned",
|
||||
1.32.IEEErem(89.765) >= 1.4705063220631647E-2 || 1.32.IEEErem(89.765) >= 1.4705063220631649E-2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.ln(Double)
|
||||
*/
|
||||
@Test fun lnD() {
|
||||
// Test for log(Double): Double
|
||||
var d = 10.0
|
||||
while (d >= -10) {
|
||||
val answer = ln(exp(d))
|
||||
assertTrue("Answer does not equal expected answer for d = " + d
|
||||
+ " answer = " + answer, abs(answer - d) <= abs(d * 0.00000001))
|
||||
d -= 0.5
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.log10(Double)
|
||||
*/
|
||||
@Test fun log10_D() {
|
||||
// Test for special cases
|
||||
assertTrue(Double.isNaN(log10(Double.NaN)))
|
||||
assertTrue(Double.isNaN(log10(-2541.05745687234187532)))
|
||||
assertTrue(Double.isNaN(log10(-0.1)))
|
||||
assertEquals(Double.POSITIVE_INFINITY, log10(Double.POSITIVE_INFINITY))
|
||||
assertEquals(Double.NEGATIVE_INFINITY, log10(0.0))
|
||||
assertEquals(Double.NEGATIVE_INFINITY, log10(+0.0))
|
||||
assertEquals(Double.NEGATIVE_INFINITY, log10(-0.0))
|
||||
|
||||
assertEquals(3.0, log10(1000.0))
|
||||
assertEquals(14.0, log10(10.0.pow(14.0)))
|
||||
assertEquals(3.7389561269540406, log10(5482.2158))
|
||||
assertEquals(14.661551142893833, log10(458723662312872.125782332587))
|
||||
assertEquals(-0.9083828622192334, log10(0.12348583358871))
|
||||
assertEquals(308.25471555991675, log10(Double.MAX_VALUE))
|
||||
assertEquals(-323.3062153431158, log10(Double.MIN_VALUE))
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.ln1p(Double)
|
||||
*/
|
||||
@Test fun ln1p_D() {
|
||||
// Test for special cases
|
||||
assertTrue("Should return NaN", Double.isNaN(ln1p(Double.NaN)))
|
||||
assertTrue("Should return NaN", Double.isNaN(ln1p(-32.0482175)))
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, ln1p(Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals(0.0.toBits(), ln1p(0.0).toBits())
|
||||
assertEquals(+0.0.toBits(), ln1p(+0.0).toBits())
|
||||
assertEquals((-0.0).toBits(), ln1p(-0.0).toBits())
|
||||
|
||||
assertEquals("Should return -0.2941782295312541", -0.2941782295312541,
|
||||
ln1p(-0.254856327), 0.0)
|
||||
assertEquals("Should return 7.368050685564151", 7.368050685564151, ln1p(1583.542), 0.0)
|
||||
assertEquals("Should return 0.4633708685409921", 0.4633708685409921,
|
||||
ln1p(0.5894227), 0.0)
|
||||
assertEquals("Should return 709.782712893384", 709.782712893384, ln1p(Double.MAX_VALUE), 0.0)
|
||||
assertEquals("Should return Double.MIN_VALUE", Double.MIN_VALUE, ln1p(Double.MIN_VALUE), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.max(Double, Double)
|
||||
*/
|
||||
@Test fun maxDD() {
|
||||
// Test for max(Double, Double): Double
|
||||
assertEquals("Incorrect Double max value", 1908897.6000089, max(-1908897.6000089,
|
||||
1908897.6000089), 0.0)
|
||||
assertEquals("Incorrect Double max value",
|
||||
1908897.6000089, max(2.0, 1908897.6000089), 0.0)
|
||||
assertEquals("Incorrect Double max value", -2.0, max(-2.0,
|
||||
-1908897.6000089), 0.0)
|
||||
|
||||
// Compare toString representations here since -0.0 = +0.0, and
|
||||
// NaN != NaN and we need to distinguish
|
||||
assertEquals((Double.NaN).toString(), max(Double.NaN, 42.0).toString(), "Max failed for NaN")
|
||||
assertEquals((Double.NaN).toString(), max(42.0, Double.NaN).toString(), "Max failed for NaN")
|
||||
assertEquals((+0.0).toString(), max(+0.0, -0.0).toString(), "Max failed for 0.0")
|
||||
assertEquals((+0.0).toString(), max(-0.0, +0.0).toString(), "Max failed for 0.0")
|
||||
assertEquals((-0.0).toString(), max(-0.0, -0.0).toString(), "Max failed for -0.0d")
|
||||
assertEquals((+0.0).toString(), max(+0.0, +0.0).toString(), "Max failed for 0.0")
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.max(float, float)
|
||||
*/
|
||||
@Test fun maxFF() {
|
||||
// Test for max(float, float): float
|
||||
assertTrue("Incorrect float max value", max(-1908897.600f,
|
||||
1908897.600f) == 1908897.600f)
|
||||
assertTrue("Incorrect float max value",
|
||||
max(2.0f, 1908897.600f) == 1908897.600f)
|
||||
assertTrue("Incorrect float max value",
|
||||
max(-2.0f, -1908897.600f) == -2.0f)
|
||||
|
||||
// Compare toString representations here since -0.0 = +0.0, and
|
||||
// NaN != NaN and we need to distinguish
|
||||
assertEquals(Float.NaN.toString(), max(Float.NaN, 42.0f).toString(), "Max failed for NaN")
|
||||
assertEquals(Float.NaN.toString(), max(42.0f, Float.NaN).toString(), "Max failed for NaN")
|
||||
assertEquals((+0.0f).toString(), max(+0.0f, -0.0f).toString(), "Max failed for 0.0")
|
||||
assertEquals((+0.0f).toString(), max(-0.0f, +0.0f).toString(), "Max failed for 0.0")
|
||||
assertEquals((-0.0f).toString(), max(-0.0f, -0.0f).toString(), "Max failed for -0.0f")
|
||||
assertEquals((+0.0f).toString(), max(+0.0f, +0.0f).toString(), "Max failed for 0.0")
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.max(int, int)
|
||||
*/
|
||||
@Test fun maxII() {
|
||||
// Test for max(int, int): int
|
||||
assertEquals("Incorrect int max value",
|
||||
19088976, max(-19088976, 19088976))
|
||||
assertEquals("Incorrect int max value",
|
||||
19088976, max(20, 19088976))
|
||||
assertEquals("Incorrect int max value", -20, max(-20, -19088976))
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.max(long, long)
|
||||
*/
|
||||
@Test fun maxJJ() {
|
||||
// Test for max(long, long): long
|
||||
assertEquals("Incorrect long max value", 19088976000089L, max(-19088976000089L,
|
||||
19088976000089L))
|
||||
assertEquals("Incorrect long max value",
|
||||
19088976000089L, max(20, 19088976000089L))
|
||||
assertEquals("Incorrect long max value",
|
||||
-20, max(-20, -19088976000089L))
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.min(Double, Double)
|
||||
*/
|
||||
@Test fun minDD() {
|
||||
// Test for min(Double, Double): Double
|
||||
assertEquals("Incorrect Double min value", -1908897.6000089, min(-1908897.6000089,
|
||||
1908897.6000089), 0.0)
|
||||
assertEquals("Incorrect Double min value",
|
||||
2.0, min(2.0, 1908897.6000089), 0.0)
|
||||
assertEquals("Incorrect Double min value", -1908897.6000089, min(-2.0,
|
||||
-1908897.6000089), 0.0)
|
||||
assertEquals("Incorrect Double min value", 1.0, min(1.0, 1.0))
|
||||
|
||||
// Compare toString representations here since -0.0 = +0.0, and
|
||||
// NaN != NaN and we need to distinguish
|
||||
assertEquals(Double.NaN.toString(), min(Double.NaN, 42.0).toString(), "Min failed for NaN")
|
||||
assertEquals(Double.NaN.toString(), min(42.0, Double.NaN).toString(), "Min failed for NaN")
|
||||
assertEquals((-0.0).toString(), min(+0.0, -0.0).toString(), "Min failed for -0.0")
|
||||
assertEquals((-0.0).toString(), min(-0.0, +0.0).toString(), "Min failed for -0.0")
|
||||
assertEquals((-0.0).toString(), min(-0.0, -0.0).toString(), "Min failed for -0.0d")
|
||||
assertEquals((+0.0).toString(), min(+0.0, +0.0).toString(), "Min failed for 0.0")
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.min(float, float)
|
||||
*/
|
||||
@Test fun minFF() {
|
||||
// Test for min(float, float): float
|
||||
assertTrue("Incorrect float min value", min(-1908897.600f,
|
||||
1908897.600f) == -1908897.600f)
|
||||
assertTrue("Incorrect float min value",
|
||||
min(2.0f, 1908897.600f) == 2.0f)
|
||||
assertTrue("Incorrect float min value",
|
||||
min(-2.0f, -1908897.600f) == -1908897.600f)
|
||||
assertEquals("Incorrect float min value", 1.0f, min(1.0f, 1.0f))
|
||||
|
||||
// Compare toString representations here since -0.0 = +0.0, and
|
||||
// NaN != NaN and we need to distinguish
|
||||
assertEquals(Float.NaN.toString(), min(Float.NaN, 42.0f).toString(), "Min failed for NaN")
|
||||
assertEquals(Float.NaN.toString(), min(42.0f, Float.NaN).toString(), "Min failed for NaN")
|
||||
assertEquals((-0.0f).toString(), min(+0.0f, -0.0f).toString(), "Min failed for -0.0")
|
||||
assertEquals((-0.0f).toString(), min(-0.0f, +0.0f).toString(), "Min failed for -0.0")
|
||||
assertEquals((-0.0f).toString(), min(-0.0f, -0.0f).toString(), "Min failed for -0.0f")
|
||||
assertEquals((+0.0f).toString(), min(+0.0f, +0.0f).toString(), "Min failed for 0.0")
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.min(int, int)
|
||||
*/
|
||||
@Test fun minII() {
|
||||
// Test for min(int, int): int
|
||||
assertEquals("Incorrect int min value",
|
||||
-19088976, min(-19088976, 19088976))
|
||||
assertEquals("Incorrect int min value", 20, min(20, 19088976))
|
||||
assertEquals("Incorrect int min value",
|
||||
-19088976, min(-20, -19088976))
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @tests java.lang.Math#pow(double, double)
|
||||
*/
|
||||
fun test_powDD() {
|
||||
// Test for method double java.lang.Math.pow(double, double)
|
||||
assertTrue("pow returned incorrect value",
|
||||
2.0.pow(8.0).toLong() == 256L)
|
||||
assertTrue("pow returned incorrect value",
|
||||
2.0.pow(-8.0) == 0.00390625)
|
||||
assertEquals("Incorrect root returned1",
|
||||
2.0, sqrt(sqrt(2.0).pow(4.0)), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.round(Double)
|
||||
*/
|
||||
@Test fun roundD() {
|
||||
// Test for round(Double): Double
|
||||
assertEquals("Failed to round properly - up to odd",
|
||||
3.0, round(2.9), 0.0)
|
||||
assertTrue("Failed to round properly - NaN", Double.isNaN(round(Double.NaN)))
|
||||
assertEquals("Failed to round properly down to even",
|
||||
2.0, round(2.1), 0.0)
|
||||
assertTrue("Failed to round properly " + 2.5 + " to even", round(2.5) == 2.0)
|
||||
assertTrue("Failed to round properly " + +0.0,
|
||||
round(+0.0) == +0.0)
|
||||
assertTrue("Failed to round properly " + -0.0,
|
||||
round(-0.0) == -0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.sign(Double)
|
||||
*/
|
||||
@Test fun sign_D() {
|
||||
assertTrue(Double.isNaN(sign(Double.NaN)))
|
||||
assertTrue(Double.isNaN(sign(Double.NaN)))
|
||||
assertEquals(0.0.toBits(), sign(0.0).toBits())
|
||||
assertEquals(+0.0.toBits(), sign(+0.0).toBits())
|
||||
assertEquals((-0.0).toBits(), sign(-0.0).toBits())
|
||||
|
||||
assertEquals(1.0, sign(253681.2187962), 0.0)
|
||||
assertEquals(-1.0, sign(-125874693.56), 0.0)
|
||||
assertEquals(1.0, sign(1.2587E-308), 0.0)
|
||||
assertEquals(-1.0, sign(-1.2587E-308), 0.0)
|
||||
|
||||
assertEquals(1.0, sign(Double.MAX_VALUE), 0.0)
|
||||
assertEquals(1.0, sign(Double.MIN_VALUE), 0.0)
|
||||
assertEquals(-1.0, sign(-Double.MAX_VALUE), 0.0)
|
||||
assertEquals(-1.0, sign(-Double.MIN_VALUE), 0.0)
|
||||
assertEquals(1.0, sign(Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals(-1.0, sign(Double.NEGATIVE_INFINITY), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.sign(float)
|
||||
*/
|
||||
@Test fun sign_F() {
|
||||
assertTrue(Float.isNaN(sign(Float.NaN)))
|
||||
assertEquals(0.0f.toBits(), sign(0.0f).toBits())
|
||||
assertEquals(+0.0f.toBits(), sign(+0.0f).toBits())
|
||||
assertEquals((-0.0f).toBits(), sign(-0.0f).toBits())
|
||||
|
||||
assertEquals(1.0f, sign(253681.2187962f), 0f)
|
||||
assertEquals(-1.0f, sign(-125874693.56f), 0f)
|
||||
assertEquals(1.0f, sign(1.2587E-11f), 0f)
|
||||
assertEquals(-1.0f, sign(-1.2587E-11f), 0f)
|
||||
|
||||
assertEquals(1.0f, sign(Float.MAX_VALUE), 0f)
|
||||
assertEquals(1.0f, sign(Float.MIN_VALUE), 0f)
|
||||
assertEquals(-1.0f, sign(-Float.MAX_VALUE), 0f)
|
||||
assertEquals(-1.0f, sign(-Float.MIN_VALUE), 0f)
|
||||
assertEquals(1.0f, sign(Float.POSITIVE_INFINITY), 0f)
|
||||
assertEquals(-1.0f, sign(Float.NEGATIVE_INFINITY), 0f)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.sin(Double)
|
||||
*/
|
||||
@Test fun sinD() {
|
||||
// Test for sin(Double): Double
|
||||
assertEquals("Incorrect answer", 0.0, sin(0.0), 0.0)
|
||||
assertEquals("Incorrect answer", 0.8414709848078965, sin(1.0), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.sinh(Double)
|
||||
*/
|
||||
@Test fun sinh_D() {
|
||||
// Test for special situations
|
||||
assertTrue("Should return NaN", Double.isNaN(sinh(Double.NaN)))
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, sinh(Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals("Should return NEGATIVE_INFINITY",
|
||||
Double.NEGATIVE_INFINITY, sinh(Double.NEGATIVE_INFINITY), 0.0)
|
||||
assertEquals(0.0.toBits(), sinh(0.0).toBits())
|
||||
assertEquals(+0.0.toBits(), sinh(+0.0).toBits())
|
||||
assertEquals((-0.0).toBits(), sinh(-0.0).toBits())
|
||||
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, sinh(1234.56), 0.0)
|
||||
assertEquals("Should return NEGATIVE_INFINITY",
|
||||
Double.NEGATIVE_INFINITY, sinh(-1234.56), 0.0)
|
||||
assertEquals("Should return 1.0000000000001666E-6",
|
||||
1.0000000000001666E-6, sinh(0.000001), 0.0)
|
||||
assertEquals("Should return -1.0000000000001666E-6",
|
||||
-1.0000000000001666E-6, sinh(-0.000001), 0.0)
|
||||
assertEquals("Should return 5.115386441963859", 5.115386441963859, sinh(2.33482))
|
||||
assertEquals("Should return POSITIVE_INFINITY",
|
||||
Double.POSITIVE_INFINITY, sinh(Double.MAX_VALUE), 0.0)
|
||||
assertEquals("Should return 4.9E-324", 4.9E-324, sinh(Double.MIN_VALUE), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.sqrt(Double)
|
||||
*/
|
||||
@Test fun sqrt_D() {
|
||||
// Test for sqrt(Double): Double
|
||||
assertEquals("Incorrect root returned2", 7.0, sqrt(49.0), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.tan(Double)
|
||||
*/
|
||||
@Test fun tan_D() {
|
||||
// Test for tan(Double): Double
|
||||
assertEquals("Incorrect answer", 0.0, tan(0.0), 0.0)
|
||||
assertEquals("Incorrect answer", 1.5574077246549023, tan(1.0))
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.math.tanh(Double)
|
||||
*/
|
||||
@Test fun tanh_D() {
|
||||
// Test for special situations
|
||||
assertTrue("Should return NaN", Double.isNaN(tanh(Double.NaN)))
|
||||
assertEquals("Should return +1.0", +1.0, tanh(Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals("Should return -1.0", -1.0, tanh(Double.NEGATIVE_INFINITY), 0.0)
|
||||
assertEquals(0.0.toBits(), tanh(0.0).toBits())
|
||||
assertEquals(+0.0.toBits(), tanh(+0.0).toBits())
|
||||
assertEquals((-0.0).toBits(), tanh(-0.0).toBits())
|
||||
|
||||
assertEquals("Should return 1.0", 1.0, tanh(1234.56), 0.0)
|
||||
assertEquals("Should return -1.0", -1.0, tanh(-1234.56), 0.0)
|
||||
assertEquals("Should return 9.999999999996666E-7",
|
||||
9.999999999996666E-7, tanh(0.000001), 0.0)
|
||||
assertEquals("Should return 0.981422884124941", 0.981422884124941, tanh(2.33482), 0.0)
|
||||
assertEquals("Should return 1.0", 1.0, tanh(Double.MAX_VALUE), 0.0)
|
||||
assertEquals("Should return 4.9E-324", 4.9E-324, tanh(Double.MIN_VALUE), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.Double.ulp
|
||||
*/
|
||||
fun test_ulp_D() {
|
||||
// Test for special cases
|
||||
assertTrue("Should return NaN", Double.isNaN(ulp(Double.NaN)))
|
||||
assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, ulp(Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, ulp(Double.NEGATIVE_INFINITY), 0.0)
|
||||
assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(0.0), 0.0)
|
||||
assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(+0.0), 0.0)
|
||||
assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(-0.0), 0.0)
|
||||
assertEquals("Returned incorrect value", pow(2.0, 971.0), ulp(Double.MAX_VALUE), 0.0)
|
||||
assertEquals("Returned incorrect value", pow(2.0, 971.0), ulp(-Double.MAX_VALUE), 0.0)
|
||||
|
||||
assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(Double.MIN_VALUE), 0.0)
|
||||
assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(-Double.MIN_VALUE), 0.0)
|
||||
|
||||
assertEquals("Returned incorrect value", 2.220446049250313E-16, ulp(1.0), 0.0)
|
||||
assertEquals("Returned incorrect value", 2.220446049250313E-16, ulp(-1.0), 0.0)
|
||||
assertEquals("Returned incorrect value", 2.2737367544323206E-13, ulp(1153.0), 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests kotlin.Float.ulp
|
||||
*/
|
||||
fun test_ulp_f() {
|
||||
// Test for special cases
|
||||
assertTrue("Should return NaN", Float.isNaN(ulp(Float.NaN)))
|
||||
assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, ulp(Float.POSITIVE_INFINITY), 0f)
|
||||
assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, ulp(Float.NEGATIVE_INFINITY), 0f)
|
||||
assertEquals("Returned incorrect value", Float.MIN_VALUE, ulp(0.0f), 0f)
|
||||
assertEquals("Returned incorrect value", Float.MIN_VALUE, ulp(+0.0f), 0f)
|
||||
assertEquals("Returned incorrect value", Float.MIN_VALUE, ulp(-0.0f), 0f)
|
||||
assertEquals("Returned incorrect value", 2.028241E31f, ulp(Float.MAX_VALUE), 0f)
|
||||
assertEquals("Returned incorrect value", 2.028241E31f, ulp(-Float.MAX_VALUE), 0f)
|
||||
|
||||
assertEquals("Returned incorrect value", 1.4E-45f, ulp(Float.MIN_VALUE), 0f)
|
||||
assertEquals("Returned incorrect value", 1.4E-45f, ulp(-Float.MIN_VALUE), 0f)
|
||||
|
||||
assertEquals("Returned incorrect value", 1.1920929E-7f, ulp(1.0f),
|
||||
0f)
|
||||
assertEquals("Returned incorrect value", 1.1920929E-7f,
|
||||
ulp(-1.0f), 0f)
|
||||
assertEquals("Returned incorrect value", 1.2207031E-4f, ulp(1153.0f), 0f)
|
||||
assertEquals("Returned incorrect value", 5.6E-45f, ulp(9.403954E-38f), 0f)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val MIN_NORMAL_D: Double = 2.2250738585072014E-308
|
||||
const val MIN_NORMAL_F: Float = 1.1754943508222875E-38f
|
||||
|
||||
/**
|
||||
* cases for test_copySign_DD in est/Strictest
|
||||
*/
|
||||
internal val COPYSIGN_DD_CASES = doubleArrayOf(Double.POSITIVE_INFINITY, Double.MAX_VALUE, 3.4E302, 2.3,
|
||||
MIN_NORMAL_D, MIN_NORMAL_D / 2, Double.MIN_VALUE, +0.0, 0.0, -0.0, -Double.MIN_VALUE,
|
||||
-MIN_NORMAL_D / 2, -MIN_NORMAL_D, -4.5, -3.4E102, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY)
|
||||
|
||||
/**
|
||||
* cases for test_copySign_FF in est/Strictest
|
||||
*/
|
||||
internal val COPYSIGN_FF_CASES = floatArrayOf(Float.POSITIVE_INFINITY, Float.MAX_VALUE, 3.4E12f, 2.3f,
|
||||
MIN_NORMAL_F, MIN_NORMAL_F / 2, Float.MIN_VALUE, +0.0f, 0.0f, -0.0f, -Float.MIN_VALUE,
|
||||
-MIN_NORMAL_F / 2, -MIN_NORMAL_F, -4.5f, -5.6442E21f, -Float.MAX_VALUE, Float.NEGATIVE_INFINITY)
|
||||
|
||||
/**
|
||||
* start number cases for test_nextTowards_DD in est/Strictest
|
||||
* NEXTAFTER_DD_START_CASES[i][0] is the start number
|
||||
* NEXTAFTER_DD_START_CASES[i][1] is the nextUp of start number
|
||||
* NEXTAFTER_DD_START_CASES[i][2] is the nextDown of start number
|
||||
*/
|
||||
internal val NEXTAFTER_DD_START_CASES = arrayOf(
|
||||
doubleArrayOf(3.4, 3.4000000000000004, 3.3999999999999995),
|
||||
doubleArrayOf(-3.4, -3.3999999999999995, -3.4000000000000004),
|
||||
doubleArrayOf(3.4233E109, 3.4233000000000005E109, 3.4232999999999996E109),
|
||||
doubleArrayOf(-3.4233E109, -3.4232999999999996E109, -3.4233000000000005E109),
|
||||
doubleArrayOf(+0.0, Double.MIN_VALUE, -Double.MIN_VALUE),
|
||||
doubleArrayOf(0.0, Double.MIN_VALUE, -Double.MIN_VALUE),
|
||||
doubleArrayOf(-0.0, Double.MIN_VALUE, -Double.MIN_VALUE),
|
||||
doubleArrayOf(Double.MIN_VALUE, 1.0E-323, +0.0),
|
||||
doubleArrayOf(-Double.MIN_VALUE, -0.0, -1.0E-323),
|
||||
doubleArrayOf(MIN_NORMAL_D, 2.225073858507202E-308, 2.225073858507201E-308),
|
||||
doubleArrayOf(-MIN_NORMAL_D, -2.225073858507201E-308, -2.225073858507202E-308),
|
||||
doubleArrayOf(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1.7976931348623155E308),
|
||||
doubleArrayOf(-Double.MAX_VALUE, -1.7976931348623155E308, Double.NEGATIVE_INFINITY),
|
||||
doubleArrayOf(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.MAX_VALUE),
|
||||
doubleArrayOf(Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY)
|
||||
)
|
||||
|
||||
/**
|
||||
* direction number cases for test_nextTowards_DD/test_nextTowards_FD in
|
||||
* est/Strictest
|
||||
*/
|
||||
internal val NEXTAFTER_DD_FD_DIRECTION_CASES = doubleArrayOf(Double.POSITIVE_INFINITY,
|
||||
Double.MAX_VALUE, 8.8, 3.4, 1.4, MIN_NORMAL_D, MIN_NORMAL_D / 2,
|
||||
Double.MIN_VALUE, +0.0, 0.0, -0.0, -Double.MIN_VALUE, -MIN_NORMAL_D / 2,
|
||||
-MIN_NORMAL_D, -1.4, -3.4, -8.8, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY)
|
||||
|
||||
/**
|
||||
* start number cases for test_nextTowards_FD in est/Strictest
|
||||
* NEXTAFTER_FD_START_CASES[i][0] is the start number
|
||||
* NEXTAFTER_FD_START_CASES[i][1] is the nextUp of start number
|
||||
* NEXTAFTER_FD_START_CASES[i][2] is the nextDown of start number
|
||||
*/
|
||||
internal val NEXTAFTER_FD_START_CASES = arrayOf(floatArrayOf(3.4f, 3.4000003f, 3.3999999f),
|
||||
floatArrayOf(-3.4f, -3.3999999f, -3.4000003f),
|
||||
floatArrayOf(3.4233E19f, 3.4233002E19f, 3.4232998E19f),
|
||||
floatArrayOf(-3.4233E19f, -3.4232998E19f, -3.4233002E19f),
|
||||
floatArrayOf(+0.0f, Float.MIN_VALUE, -Float.MIN_VALUE),
|
||||
floatArrayOf(0.0f, Float.MIN_VALUE, -Float.MIN_VALUE),
|
||||
floatArrayOf(-0.0f, Float.MIN_VALUE, -Float.MIN_VALUE),
|
||||
floatArrayOf(Float.MIN_VALUE, 2.8E-45f, +0.0f),
|
||||
floatArrayOf(-Float.MIN_VALUE, -0.0f, -2.8E-45f),
|
||||
floatArrayOf(MIN_NORMAL_F, 1.1754945E-38f, 1.1754942E-38f),
|
||||
floatArrayOf(-MIN_NORMAL_F, -1.1754942E-38f, -1.1754945E-38f),
|
||||
floatArrayOf(Float.MAX_VALUE, Float.POSITIVE_INFINITY, 3.4028233E38f),
|
||||
floatArrayOf(-Float.MAX_VALUE, -3.4028233E38f, Float.NEGATIVE_INFINITY),
|
||||
floatArrayOf(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.MAX_VALUE),
|
||||
floatArrayOf(Float.NEGATIVE_INFINITY, -Float.MAX_VALUE, Float.NEGATIVE_INFINITY))
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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 test.numbers
|
||||
|
||||
import kotlin.math.*
|
||||
import kotlin.test.*
|
||||
|
||||
class MathExceptionTest {
|
||||
|
||||
@Test fun exceptions() {
|
||||
assertFails { Double.NaN.roundToLong() }
|
||||
assertFails { Double.NaN.roundToInt() }
|
||||
|
||||
assertFails { Float.NaN.roundToLong() }
|
||||
assertFails { Float.NaN.roundToInt() }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,811 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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 test.numbers
|
||||
|
||||
import kotlin.math.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun assertAlmostEquals(expected: Double, actual: Double, tolerance: Double? = null) {
|
||||
val tolerance_ = tolerance?.let { abs(it) } ?: 0.000000000001
|
||||
if (abs(expected - actual) > tolerance_) {
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
fun assertAlmostEquals(expected: Float, actual: Float, tolerance: Double? = null) {
|
||||
val tolerance_ = tolerance?.let { abs(it) } ?: 0.0000001
|
||||
if (abs(expected - actual) > tolerance_) {
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
class DoubleMathTest {
|
||||
|
||||
@Test fun trigonometric() {
|
||||
assertEquals(0.0, sin(0.0))
|
||||
assertAlmostEquals(0.0, sin(PI))
|
||||
|
||||
assertEquals(0.0, asin(0.0))
|
||||
assertAlmostEquals(PI / 2, asin(1.0))
|
||||
|
||||
assertEquals(1.0, cos(0.0))
|
||||
assertAlmostEquals(-1.0, cos(PI))
|
||||
|
||||
assertEquals(0.0, acos(1.0))
|
||||
assertAlmostEquals(PI / 2, acos(0.0))
|
||||
|
||||
assertEquals(0.0, tan(0.0))
|
||||
assertAlmostEquals(1.0, tan(PI / 4))
|
||||
|
||||
assertAlmostEquals(0.0, atan(0.0))
|
||||
assertAlmostEquals(PI / 4, atan(1.0))
|
||||
|
||||
assertAlmostEquals(PI / 4, atan2(10.0, 10.0))
|
||||
assertAlmostEquals(-PI / 4, atan2(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY))
|
||||
assertAlmostEquals(0.0, atan2(0.0, 0.0))
|
||||
assertAlmostEquals(0.0, atan2(0.0, 10.0))
|
||||
assertAlmostEquals(PI / 2, atan2(2.0, 0.0))
|
||||
|
||||
for (angle in listOf(Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY)) {
|
||||
assertTrue(sin(angle).isNaN(), "sin($angle)")
|
||||
assertTrue(cos(angle).isNaN(), "cos($angle)")
|
||||
assertTrue(tan(angle).isNaN(), "tan($angle)")
|
||||
}
|
||||
|
||||
for (value in listOf(Double.NaN, 1.2, -1.1)) {
|
||||
assertTrue(asin(value).isNaN())
|
||||
assertTrue(acos(value).isNaN())
|
||||
}
|
||||
assertTrue(atan(Double.NaN).isNaN())
|
||||
assertTrue(atan2(Double.NaN, 0.0).isNaN())
|
||||
assertTrue(atan2(0.0, Double.NaN).isNaN())
|
||||
}
|
||||
|
||||
@Test fun hyperbolic() {
|
||||
assertEquals(Double.POSITIVE_INFINITY, sinh(Double.POSITIVE_INFINITY))
|
||||
assertEquals(Double.NEGATIVE_INFINITY, sinh(Double.NEGATIVE_INFINITY))
|
||||
assertTrue(sinh(Double.MIN_VALUE) != 0.0)
|
||||
assertTrue(sinh(710.0).isFinite())
|
||||
assertTrue(sinh(-710.0).isFinite())
|
||||
assertTrue(sinh(Double.NaN).isNaN())
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, cosh(Double.POSITIVE_INFINITY))
|
||||
assertEquals(Double.POSITIVE_INFINITY, cosh(Double.NEGATIVE_INFINITY))
|
||||
assertTrue(cosh(710.0).isFinite())
|
||||
assertTrue(cosh(-710.0).isFinite())
|
||||
assertTrue(cosh(Double.NaN).isNaN())
|
||||
|
||||
assertAlmostEquals(1.0, tanh(Double.POSITIVE_INFINITY))
|
||||
assertAlmostEquals(-1.0, tanh(Double.NEGATIVE_INFINITY))
|
||||
assertTrue(tanh(Double.MIN_VALUE) != 0.0)
|
||||
assertTrue(tanh(Double.NaN).isNaN())
|
||||
}
|
||||
|
||||
@Test fun inverseHyperbolicSin() {
|
||||
for (exact in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0, Double.MIN_VALUE, -Double.MIN_VALUE, 0.00001)) {
|
||||
assertEquals(exact, asinh(sinh(exact)))
|
||||
}
|
||||
for (approx in listOf(Double.MIN_VALUE, 0.1, 1.0, 100.0, 710.0)) {
|
||||
assertAlmostEquals(approx, asinh(sinh(approx)))
|
||||
assertAlmostEquals(-approx, asinh(sinh(-approx)))
|
||||
}
|
||||
assertTrue(asinh(Double.NaN).isNaN())
|
||||
}
|
||||
|
||||
@Test fun inverseHyperbolicCos() {
|
||||
for (exact in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0)) {
|
||||
assertEquals(abs(exact), acosh(cosh(exact)))
|
||||
}
|
||||
for (approx in listOf(Double.MIN_VALUE, 0.00001, 1.0, 100.0, 710.0)) {
|
||||
assertAlmostEquals(approx, acosh(cosh(approx)))
|
||||
assertAlmostEquals(approx, acosh(cosh(-approx)))
|
||||
}
|
||||
for (invalid in listOf(-1.0, 0.0, 0.99999, Double.NaN)) {
|
||||
assertTrue(acosh(invalid).isNaN())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun inverseHyperbolicTan() {
|
||||
for (exact in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0, Double.MIN_VALUE, -Double.MIN_VALUE)) {
|
||||
assertEquals(exact, atanh(tanh(exact)))
|
||||
}
|
||||
for (approx in listOf(0.00001)) {
|
||||
assertAlmostEquals(approx, atanh(tanh(approx)))
|
||||
}
|
||||
|
||||
for (invalid in listOf(-1.00001, 1.00001, Double.NaN, Double.MAX_VALUE, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) {
|
||||
assertTrue(atanh(invalid).isNaN())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun powers() {
|
||||
assertEquals(5.0, hypot(3.0, 4.0))
|
||||
assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY, Double.NaN))
|
||||
assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NaN, Double.POSITIVE_INFINITY))
|
||||
assertTrue(hypot(Double.NaN, 0.0).isNaN())
|
||||
|
||||
assertEquals(1.0, Double.NaN.pow(0.0))
|
||||
assertEquals(1.0, Double.POSITIVE_INFINITY.pow(0))
|
||||
assertEquals(49.0, 7.0.pow(2))
|
||||
assertEquals(0.25, 2.0.pow(-2))
|
||||
assertTrue(0.0.pow(Double.NaN).isNaN())
|
||||
assertTrue(Double.NaN.pow(-1).isNaN())
|
||||
assertTrue((-7.0).pow(1/3.0).isNaN())
|
||||
assertTrue(1.0.pow(Double.POSITIVE_INFINITY).isNaN())
|
||||
assertTrue((-1.0).pow(Double.NEGATIVE_INFINITY).isNaN())
|
||||
|
||||
assertEquals(5.0, sqrt(9.0 + 16.0))
|
||||
assertTrue(sqrt(-1.0).isNaN())
|
||||
assertTrue(sqrt(Double.NaN).isNaN())
|
||||
|
||||
assertTrue(exp(Double.NaN).isNaN())
|
||||
assertAlmostEquals(E, exp(1.0))
|
||||
assertEquals(1.0, exp(0.0))
|
||||
assertEquals(0.0, exp(Double.NEGATIVE_INFINITY))
|
||||
assertEquals(Double.POSITIVE_INFINITY, exp(Double.POSITIVE_INFINITY))
|
||||
|
||||
assertEquals(0.0, expm1(0.0))
|
||||
assertEquals(Double.MIN_VALUE, expm1(Double.MIN_VALUE))
|
||||
assertEquals(0.00010000500016667084, expm1(1e-4))
|
||||
assertEquals(-1.0, expm1(Double.NEGATIVE_INFINITY))
|
||||
assertEquals(Double.POSITIVE_INFINITY, expm1(Double.POSITIVE_INFINITY))
|
||||
}
|
||||
|
||||
@Test fun logarithms() {
|
||||
assertTrue(log(1.0, Double.NaN).isNaN())
|
||||
assertTrue(log(Double.NaN, 1.0).isNaN())
|
||||
assertTrue(log(-1.0, 2.0).isNaN())
|
||||
assertTrue(log(2.0, -1.0).isNaN())
|
||||
assertTrue(log(2.0, 0.0).isNaN())
|
||||
assertTrue(log(2.0, 1.0).isNaN())
|
||||
assertTrue(log(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY).isNaN())
|
||||
assertEquals(-2.0, log(0.25, 2.0))
|
||||
assertEquals(-0.5, log(2.0, 0.25))
|
||||
assertEquals(Double.NEGATIVE_INFINITY, log(Double.POSITIVE_INFINITY, 0.25))
|
||||
assertEquals(Double.POSITIVE_INFINITY, log(Double.POSITIVE_INFINITY, 2.0))
|
||||
assertEquals(Double.NEGATIVE_INFINITY, log(0.0, 2.0))
|
||||
assertEquals(Double.POSITIVE_INFINITY, log(0.0, 0.25))
|
||||
|
||||
assertTrue(ln(Double.NaN).isNaN())
|
||||
assertTrue(ln(-1.0).isNaN())
|
||||
assertEquals(1.0, ln(E))
|
||||
assertEquals(Double.NEGATIVE_INFINITY, ln(0.0))
|
||||
assertEquals(Double.POSITIVE_INFINITY, ln(Double.POSITIVE_INFINITY))
|
||||
|
||||
assertEquals(1.0, log10(10.0))
|
||||
assertAlmostEquals(-1.0, log10(0.1))
|
||||
|
||||
assertAlmostEquals(3.0, log2(8.0))
|
||||
assertEquals(-1.0, log2(0.5))
|
||||
|
||||
assertTrue(ln1p(Double.NaN).isNaN())
|
||||
assertTrue(ln1p(-1.1).isNaN())
|
||||
assertEquals(0.0, ln1p(0.0))
|
||||
assertEquals(9.999995000003334e-7, ln1p(1e-6))
|
||||
assertEquals(Double.MIN_VALUE, ln1p(Double.MIN_VALUE))
|
||||
assertEquals(Double.NEGATIVE_INFINITY, ln1p(-1.0))
|
||||
}
|
||||
|
||||
@Test fun rounding() {
|
||||
for (value in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0, 1.0, -10.0)) {
|
||||
assertEquals(value, ceil(value))
|
||||
assertEquals(value, floor(value))
|
||||
assertEquals(value, truncate(value))
|
||||
assertEquals(value, round(value))
|
||||
}
|
||||
assertTrue(ceil(Double.NaN).isNaN())
|
||||
assertTrue(floor(Double.NaN).isNaN())
|
||||
assertTrue(truncate(Double.NaN).isNaN())
|
||||
assertTrue(round(Double.NaN).isNaN())
|
||||
val data = arrayOf( // v floor trunc round ceil
|
||||
doubleArrayOf( 1.3, 1.0, 1.0, 1.0, 2.0),
|
||||
doubleArrayOf(-1.3, -2.0, -1.0, -1.0, -1.0),
|
||||
doubleArrayOf( 1.5, 1.0, 1.0, 2.0, 2.0),
|
||||
doubleArrayOf(-1.5, -2.0, -1.0, -2.0, -1.0),
|
||||
doubleArrayOf( 1.8, 1.0, 1.0, 2.0, 2.0),
|
||||
doubleArrayOf(-1.8, -2.0, -1.0, -2.0, -1.0),
|
||||
|
||||
doubleArrayOf( 2.3, 2.0, 2.0, 2.0, 3.0),
|
||||
doubleArrayOf(-2.3, -3.0, -2.0, -2.0, -2.0),
|
||||
doubleArrayOf( 2.5, 2.0, 2.0, 2.0, 3.0),
|
||||
doubleArrayOf(-2.5, -3.0, -2.0, -2.0, -2.0),
|
||||
doubleArrayOf( 2.8, 2.0, 2.0, 3.0, 3.0),
|
||||
doubleArrayOf(-2.8, -3.0, -2.0, -3.0, -2.0)
|
||||
)
|
||||
for ((v, f, t, r, c) in data) {
|
||||
assertEquals(f, floor(v), "floor($v)")
|
||||
assertEquals(t, truncate(v), "truncate($v)")
|
||||
assertEquals(r, round(v), "round($v)")
|
||||
assertEquals(c, ceil(v), "ceil($v)")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun roundingConversion() {
|
||||
assertEquals(1L, 1.0.roundToLong())
|
||||
assertEquals(1L, 1.1.roundToLong())
|
||||
assertEquals(2L, 1.5.roundToLong())
|
||||
assertEquals(3L, 2.5.roundToLong())
|
||||
assertEquals(-2L, (-2.5).roundToLong())
|
||||
assertEquals(-3L, (-2.6).roundToLong())
|
||||
assertEquals(9223372036854774784, (9223372036854774800.0).roundToLong())
|
||||
assertEquals(Long.MAX_VALUE, Double.MAX_VALUE.roundToLong())
|
||||
assertEquals(Long.MIN_VALUE, (-Double.MAX_VALUE).roundToLong())
|
||||
assertEquals(Long.MAX_VALUE, Double.POSITIVE_INFINITY.roundToLong())
|
||||
assertEquals(Long.MIN_VALUE, Double.NEGATIVE_INFINITY.roundToLong())
|
||||
|
||||
assertEquals(1, 1.0.roundToInt())
|
||||
assertEquals(1, 1.1.roundToInt())
|
||||
assertEquals(2, 1.5.roundToInt())
|
||||
assertEquals(3, 2.5.roundToInt())
|
||||
assertEquals(-2, (-2.5).roundToInt())
|
||||
assertEquals(-3, (-2.6).roundToInt())
|
||||
assertEquals(2123456789, (2123456789.0).roundToInt())
|
||||
assertEquals(Int.MAX_VALUE, Double.MAX_VALUE.roundToInt())
|
||||
assertEquals(Int.MIN_VALUE, (-Double.MAX_VALUE).roundToInt())
|
||||
assertEquals(Int.MAX_VALUE, Double.POSITIVE_INFINITY.roundToInt())
|
||||
assertEquals(Int.MIN_VALUE, Double.NEGATIVE_INFINITY.roundToInt())
|
||||
}
|
||||
|
||||
@Test fun absoluteValue() {
|
||||
assertTrue(abs(Double.NaN).isNaN())
|
||||
assertTrue(Double.NaN.absoluteValue.isNaN())
|
||||
|
||||
for (value in listOf(0.0, Double.MIN_VALUE, 0.1, 1.0, 1000.0, Double.MAX_VALUE, Double.POSITIVE_INFINITY)) {
|
||||
assertEquals(value, value.absoluteValue)
|
||||
assertEquals(value, (-value).absoluteValue)
|
||||
assertEquals(value, abs(value))
|
||||
assertEquals(value, abs(-value))
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun signs() {
|
||||
assertTrue(sign(Double.NaN).isNaN())
|
||||
assertTrue(Double.NaN.sign.isNaN())
|
||||
|
||||
val negatives = listOf(Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, -1.0, -Double.MIN_VALUE)
|
||||
for (value in negatives) {
|
||||
assertEquals(-1.0, sign(value))
|
||||
assertEquals(-1.0, value.sign)
|
||||
}
|
||||
|
||||
val zeroes = listOf(0.0, -0.0)
|
||||
for (value in zeroes) {
|
||||
assertEquals(value, sign(value))
|
||||
assertEquals(value, value.sign)
|
||||
}
|
||||
|
||||
|
||||
val positives = listOf(Double.POSITIVE_INFINITY, Double.MAX_VALUE, 1.0, Double.MIN_VALUE)
|
||||
for (value in positives) {
|
||||
assertEquals(1.0, sign(value))
|
||||
assertEquals(1.0, value.sign)
|
||||
}
|
||||
|
||||
val allValues = negatives + positives
|
||||
for (a in allValues) {
|
||||
for (b in allValues) {
|
||||
val r = a.withSign(b)
|
||||
assertEquals(a.absoluteValue, r.absoluteValue)
|
||||
assertEquals(b.sign, r.sign, "expected $a with sign bit of $b to have sign ${b.sign}")
|
||||
}
|
||||
|
||||
val rp0 = a.withSign(0.0)
|
||||
assertEquals(1.0, rp0.sign)
|
||||
assertEquals(a.absoluteValue, rp0.absoluteValue)
|
||||
|
||||
val rm0 = a.withSign(-0.0)
|
||||
assertEquals(-1.0, rm0.sign)
|
||||
assertEquals(a.absoluteValue, rm0.absoluteValue)
|
||||
|
||||
val ri = a.withSign(-1)
|
||||
assertEquals(-1.0, ri.sign)
|
||||
assertEquals(a.absoluteValue, ri.absoluteValue)
|
||||
|
||||
val rn = a.withSign(Double.NaN)
|
||||
assertEquals(a.absoluteValue, rn.absoluteValue)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun nextAndPrev() {
|
||||
for (value in listOf(0.0, -0.0, Double.MIN_VALUE, -1.0, 2.0.pow(10))) {
|
||||
val next = value.nextUp()
|
||||
if (next > 0) {
|
||||
assertEquals(next, value + value.ulp)
|
||||
} else {
|
||||
assertEquals(value, next - next.ulp)
|
||||
}
|
||||
|
||||
val prev = value.nextDown()
|
||||
if (prev > 0) {
|
||||
assertEquals(value, prev + prev.ulp)
|
||||
}
|
||||
else {
|
||||
assertEquals(prev, value - value.ulp)
|
||||
}
|
||||
|
||||
val toZero = value.nextTowards(0.0)
|
||||
if (toZero != 0.0) {
|
||||
assertEquals(value, toZero + toZero.ulp.withSign(toZero))
|
||||
}
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, Double.MAX_VALUE.nextUp())
|
||||
assertEquals(Double.MAX_VALUE, Double.POSITIVE_INFINITY.nextDown())
|
||||
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (-Double.MAX_VALUE).nextDown())
|
||||
assertEquals((-Double.MAX_VALUE), Double.NEGATIVE_INFINITY.nextUp())
|
||||
|
||||
assertTrue(Double.NaN.ulp.isNaN())
|
||||
assertTrue(Double.NaN.nextDown().isNaN())
|
||||
assertTrue(Double.NaN.nextUp().isNaN())
|
||||
assertTrue(Double.NaN.nextTowards(0.0).isNaN())
|
||||
|
||||
assertEquals(Double.MIN_VALUE, (0.0).ulp)
|
||||
assertEquals(Double.MIN_VALUE, (-0.0).ulp)
|
||||
assertEquals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY.ulp)
|
||||
assertEquals(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY.ulp)
|
||||
|
||||
val maxUlp = 2.0.pow(971)
|
||||
assertEquals(maxUlp, Double.MAX_VALUE.ulp)
|
||||
assertEquals(maxUlp, (-Double.MAX_VALUE).ulp)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun IEEEremainder() {
|
||||
val data = arrayOf( // a a IEEErem 2.5
|
||||
doubleArrayOf(-2.0, 0.5),
|
||||
doubleArrayOf(-1.25, -1.25),
|
||||
doubleArrayOf( 0.0, 0.0),
|
||||
doubleArrayOf( 1.0, 1.0),
|
||||
doubleArrayOf( 1.25, 1.25),
|
||||
doubleArrayOf( 1.5, -1.0),
|
||||
doubleArrayOf( 2.0, -0.5),
|
||||
doubleArrayOf( 2.5, 0.0),
|
||||
doubleArrayOf( 3.5, 1.0),
|
||||
doubleArrayOf( 3.75, -1.25),
|
||||
doubleArrayOf( 4.0, -1.0)
|
||||
)
|
||||
for ((a, r) in data) {
|
||||
assertEquals(r, a.IEEErem(2.5), "($a).IEEErem(2.5)")
|
||||
}
|
||||
|
||||
assertTrue(Double.NaN.IEEErem(2.5).isNaN())
|
||||
assertTrue(2.0.IEEErem(Double.NaN).isNaN())
|
||||
assertTrue(Double.POSITIVE_INFINITY.IEEErem(2.0).isNaN())
|
||||
assertTrue(2.0.IEEErem(0.0).isNaN())
|
||||
assertEquals(PI, PI.IEEErem(Double.NEGATIVE_INFINITY))
|
||||
}
|
||||
|
||||
/*
|
||||
* Special cases:
|
||||
* - `atan2(0.0, 0.0)` is `0.0`
|
||||
* - `atan2(0.0, x)` is `0.0` for `x > 0` and `PI` for `x < 0`
|
||||
* - `atan2(-0.0, x)` is `-0.0` for 'x > 0` and `-PI` for `x < 0`
|
||||
* - `atan2(y, +Inf)` is `0.0` for `0 < y < +Inf` and `-0.0` for '-Inf < y < 0`
|
||||
* - `atan2(y, -Inf)` is `PI` for `0 < y < +Inf` and `-PI` for `-Inf < y < 0`
|
||||
* - `atan2(y, 0.0)` is `PI/2` for `y > 0` and `-PI/2` for `y < 0`
|
||||
* - `atan2(+Inf, x)` is `PI/2` for finite `x`y
|
||||
* - `atan2(-Inf, x)` is `-PI/2` for finite `x`
|
||||
* - `atan2(NaN, x)` and `atan2(y, NaN)` is `NaN`
|
||||
*/
|
||||
@Test fun atan2SpecialCases() {
|
||||
|
||||
assertEquals(atan2(0.0, 0.0), 0.0)
|
||||
assertEquals(atan2(0.0, 1.0), 0.0)
|
||||
assertEquals(atan2(0.0, -1.0), PI)
|
||||
assertEquals(atan2(-0.0, 1.0), -0.0)
|
||||
assertEquals(atan2(-0.0, -1.0), -PI)
|
||||
assertEquals(atan2(1.0, Double.POSITIVE_INFINITY), 0.0)
|
||||
assertEquals(atan2(-1.0, Double.POSITIVE_INFINITY), -0.0)
|
||||
assertEquals(atan2(1.0, Double.NEGATIVE_INFINITY), PI)
|
||||
assertEquals(atan2(-1.0, Double.NEGATIVE_INFINITY), -PI)
|
||||
assertEquals(atan2(1.0, 0.0), PI/2)
|
||||
assertEquals(atan2(-1.0, 0.0), -PI/2)
|
||||
assertEquals(atan2(Double.POSITIVE_INFINITY, 1.0), PI/2)
|
||||
assertEquals(atan2(Double.NEGATIVE_INFINITY, 1.0), -PI/2)
|
||||
|
||||
assertTrue(atan2(Double.NaN, 1.0).isNaN())
|
||||
assertTrue(atan2(1.0, Double.NaN).isNaN())
|
||||
}
|
||||
}
|
||||
|
||||
class FloatMathTest {
|
||||
|
||||
companion object {
|
||||
const val PI = kotlin.math.PI.toFloat()
|
||||
const val E = kotlin.math.E.toFloat()
|
||||
}
|
||||
|
||||
@Test fun trigonometric() {
|
||||
assertEquals(0.0F, sin(0.0F))
|
||||
assertAlmostEquals(0.0F, sin(PI))
|
||||
|
||||
assertEquals(0.0F, asin(0.0F))
|
||||
assertAlmostEquals(PI / 2, asin(1.0F), 0.0000002)
|
||||
|
||||
assertEquals(1.0F, cos(0.0F))
|
||||
assertAlmostEquals(-1.0F, cos(PI))
|
||||
|
||||
assertEquals(0.0F, acos(1.0F))
|
||||
assertAlmostEquals(PI / 2, acos(0.0F))
|
||||
|
||||
assertEquals(0.0F, tan(0.0F))
|
||||
assertAlmostEquals(1.0F, tan(PI / 4))
|
||||
|
||||
assertAlmostEquals(0.0F, atan(0.0F))
|
||||
assertAlmostEquals(PI / 4, atan(1.0F))
|
||||
|
||||
assertAlmostEquals(PI / 4, atan2(10.0F, 10.0F))
|
||||
assertAlmostEquals(-PI / 4, atan2(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY))
|
||||
assertAlmostEquals(0.0F, atan2(0.0F, 0.0F))
|
||||
assertAlmostEquals(0.0F, atan2(0.0F, 10.0F))
|
||||
assertAlmostEquals(PI / 2, atan2(2.0F, 0.0F))
|
||||
|
||||
for (angle in listOf(Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY)) {
|
||||
assertTrue(sin(angle).isNaN(), "sin($angle)")
|
||||
assertTrue(cos(angle).isNaN(), "cos($angle)")
|
||||
assertTrue(tan(angle).isNaN(), "tan($angle)")
|
||||
}
|
||||
|
||||
for (value in listOf(Float.NaN, 1.2F, -1.1F)) {
|
||||
assertTrue(asin(value).isNaN())
|
||||
assertTrue(acos(value).isNaN())
|
||||
}
|
||||
assertTrue(atan(Float.NaN).isNaN())
|
||||
assertTrue(atan2(Float.NaN, 0.0F).isNaN())
|
||||
assertTrue(atan2(0.0F, Float.NaN).isNaN())
|
||||
}
|
||||
|
||||
@Test fun hyperbolic() {
|
||||
assertEquals(Float.POSITIVE_INFINITY, sinh(Float.POSITIVE_INFINITY))
|
||||
assertEquals(Float.NEGATIVE_INFINITY, sinh(Float.NEGATIVE_INFINITY))
|
||||
assertTrue(sinh(Float.MIN_VALUE) != 0.0F)
|
||||
assertTrue(sinh(89.0F).isFinite())
|
||||
assertTrue(sinh(-89.0F).isFinite())
|
||||
assertTrue(sinh(Float.NaN).isNaN())
|
||||
|
||||
assertEquals(Float.POSITIVE_INFINITY, cosh(Float.POSITIVE_INFINITY))
|
||||
assertEquals(Float.POSITIVE_INFINITY, cosh(Float.NEGATIVE_INFINITY))
|
||||
assertTrue(cosh(89.0F).isFinite())
|
||||
assertTrue(cosh(-89.0F).isFinite())
|
||||
assertTrue(cosh(Float.NaN).isNaN())
|
||||
|
||||
assertAlmostEquals(1.0F, tanh(Float.POSITIVE_INFINITY))
|
||||
assertAlmostEquals(-1.0F, tanh(Float.NEGATIVE_INFINITY))
|
||||
assertTrue(tanh(Float.MIN_VALUE) != 0.0F)
|
||||
assertTrue(tanh(Float.NaN).isNaN())
|
||||
}
|
||||
|
||||
@Test fun inverseHyperbolicSin() {
|
||||
for (exact in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0F, Float.MIN_VALUE, -Float.MIN_VALUE, 0.00001F)) {
|
||||
assertEquals(exact, asinh(sinh(exact)))
|
||||
}
|
||||
for (approx in listOf(Float.MIN_VALUE, 0.1F, 1.0F, 89.0F)) {
|
||||
assertAlmostEquals(approx, asinh(sinh(approx)))
|
||||
assertAlmostEquals(-approx, asinh(sinh(-approx)))
|
||||
}
|
||||
assertTrue(asinh(Float.NaN).isNaN())
|
||||
}
|
||||
|
||||
@Test fun inverseHyperbolicCos() {
|
||||
for (exact in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0F)) {
|
||||
assertEquals(abs(exact), acosh(cosh(exact)))
|
||||
}
|
||||
for (approx in listOf(Float.MIN_VALUE, 0.1F, 1.0F, 89.0F)) {
|
||||
assertAlmostEquals(approx, acosh(cosh(approx)))
|
||||
assertAlmostEquals(approx, acosh(cosh(-approx)))
|
||||
}
|
||||
for (invalid in listOf(-1.0F, 0.0F, 0.99999F, Float.NaN)) {
|
||||
assertTrue(acosh(invalid).isNaN())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun inverseHyperbolicTan() {
|
||||
for (exact in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0F, Float.MIN_VALUE, -Float.MIN_VALUE)) {
|
||||
assertEquals(exact, atanh(tanh(exact)))
|
||||
}
|
||||
|
||||
for (approx in listOf(0.00001F)) {
|
||||
assertAlmostEquals(approx, atanh(tanh(approx)))
|
||||
}
|
||||
|
||||
for (invalid in listOf(-1.00001F, 1.00001F, Float.NaN, Float.MAX_VALUE, -Float.MAX_VALUE, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY)) {
|
||||
assertTrue(atanh(invalid).isNaN())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun powers() {
|
||||
assertEquals(5.0F, hypot(3.0F, 4.0F))
|
||||
assertEquals(Float.POSITIVE_INFINITY, hypot(Float.NEGATIVE_INFINITY, Float.NaN))
|
||||
assertEquals(Float.POSITIVE_INFINITY, hypot(Float.NaN, Float.POSITIVE_INFINITY))
|
||||
assertTrue(hypot(Float.NaN, 0.0F).isNaN())
|
||||
|
||||
assertEquals(1.0F, Float.NaN.pow(0.0F))
|
||||
assertEquals(1.0F, Float.POSITIVE_INFINITY.pow(0))
|
||||
assertEquals(49.0F, 7.0F.pow(2))
|
||||
assertEquals(0.25F, 2.0F.pow(-2))
|
||||
assertTrue(0.0F.pow(Float.NaN).isNaN())
|
||||
assertTrue(Float.NaN.pow(-1).isNaN())
|
||||
assertTrue((-7.0F).pow(1/3.0F).isNaN())
|
||||
assertTrue(1.0F.pow(Float.POSITIVE_INFINITY).isNaN())
|
||||
assertTrue((-1.0F).pow(Float.NEGATIVE_INFINITY).isNaN())
|
||||
|
||||
assertEquals(5.0F, sqrt(9.0F + 16.0F))
|
||||
assertTrue(sqrt(-1.0F).isNaN())
|
||||
assertTrue(sqrt(Float.NaN).isNaN())
|
||||
|
||||
assertTrue(exp(Float.NaN).isNaN())
|
||||
assertAlmostEquals(E, exp(1.0F))
|
||||
assertEquals(1.0F, exp(0.0F))
|
||||
assertEquals(0.0F, exp(Float.NEGATIVE_INFINITY))
|
||||
assertEquals(Float.POSITIVE_INFINITY, exp(Float.POSITIVE_INFINITY))
|
||||
|
||||
assertEquals(0.0F, expm1(0.0F))
|
||||
assertEquals(-1.0F, expm1(Float.NEGATIVE_INFINITY))
|
||||
assertEquals(Float.POSITIVE_INFINITY, expm1(Float.POSITIVE_INFINITY))
|
||||
}
|
||||
|
||||
@Test fun logarithms() {
|
||||
assertTrue(log(1.0F, Float.NaN).isNaN())
|
||||
assertTrue(log(Float.NaN, 1.0F).isNaN())
|
||||
assertTrue(log(-1.0F, 2.0F).isNaN())
|
||||
assertTrue(log(2.0F, -1.0F).isNaN())
|
||||
assertTrue(log(2.0F, 0.0F).isNaN())
|
||||
assertTrue(log(2.0F, 1.0F).isNaN())
|
||||
assertTrue(log(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY).isNaN())
|
||||
assertEquals(-2.0F, log(0.25F, 2.0F))
|
||||
assertEquals(-0.5F, log(2.0F, 0.25F))
|
||||
assertEquals(Float.NEGATIVE_INFINITY, log(Float.POSITIVE_INFINITY, 0.25F))
|
||||
assertEquals(Float.POSITIVE_INFINITY, log(Float.POSITIVE_INFINITY, 2.0F))
|
||||
assertEquals(Float.NEGATIVE_INFINITY, log(0.0F, 2.0F))
|
||||
assertEquals(Float.POSITIVE_INFINITY, log(0.0F, 0.25F))
|
||||
|
||||
assertTrue(ln(Float.NaN).isNaN())
|
||||
assertTrue(ln(-1.0F).isNaN())
|
||||
assertAlmostEquals(1.0F, ln(E))
|
||||
assertEquals(Float.NEGATIVE_INFINITY, ln(0.0F))
|
||||
assertEquals(Float.POSITIVE_INFINITY, ln(Float.POSITIVE_INFINITY))
|
||||
|
||||
assertEquals(1.0F, log10(10.0F))
|
||||
assertAlmostEquals(-1.0F, log10(0.1F))
|
||||
|
||||
assertAlmostEquals(3.0F, log2(8.0F))
|
||||
assertEquals(-1.0F, log2(0.5F))
|
||||
|
||||
assertTrue(ln1p(Float.NaN).isNaN())
|
||||
assertTrue(ln1p(-1.1F).isNaN())
|
||||
assertEquals(0.0F, ln1p(0.0F))
|
||||
assertEquals(Float.NEGATIVE_INFINITY, ln1p(-1.0F))
|
||||
}
|
||||
|
||||
@Test fun rounding() {
|
||||
for (value in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0F, 1.0F, -10.0F)) {
|
||||
assertEquals(value, ceil(value))
|
||||
assertEquals(value, floor(value))
|
||||
assertEquals(value, truncate(value))
|
||||
assertEquals(value, round(value))
|
||||
}
|
||||
assertTrue(ceil(Float.NaN).isNaN())
|
||||
assertTrue(floor(Float.NaN).isNaN())
|
||||
assertTrue(truncate(Float.NaN).isNaN())
|
||||
assertTrue(round(Float.NaN).isNaN())
|
||||
val data = arrayOf( // v floor trunc round ceil
|
||||
floatArrayOf( 1.3F, 1.0F, 1.0F, 1.0F, 2.0F),
|
||||
floatArrayOf(-1.3F, -2.0F, -1.0F, -1.0F, -1.0F),
|
||||
floatArrayOf( 1.5F, 1.0F, 1.0F, 2.0F, 2.0F),
|
||||
floatArrayOf(-1.5F, -2.0F, -1.0F, -2.0F, -1.0F),
|
||||
floatArrayOf( 1.8F, 1.0F, 1.0F, 2.0F, 2.0F),
|
||||
floatArrayOf(-1.8F, -2.0F, -1.0F, -2.0F, -1.0F),
|
||||
|
||||
floatArrayOf( 2.3F, 2.0F, 2.0F, 2.0F, 3.0F),
|
||||
floatArrayOf(-2.3F, -3.0F, -2.0F, -2.0F, -2.0F),
|
||||
floatArrayOf( 2.5F, 2.0F, 2.0F, 2.0F, 3.0F),
|
||||
floatArrayOf(-2.5F, -3.0F, -2.0F, -2.0F, -2.0F),
|
||||
floatArrayOf( 2.8F, 2.0F, 2.0F, 3.0F, 3.0F),
|
||||
floatArrayOf(-2.8F, -3.0F, -2.0F, -3.0F, -2.0F)
|
||||
)
|
||||
for ((v, f, t, r, c) in data) {
|
||||
assertEquals(f, floor(v), "floor($v)")
|
||||
assertEquals(t, truncate(v), "truncate($v)")
|
||||
assertEquals(r, round(v), "round($v)")
|
||||
assertEquals(c, ceil(v), "ceil($v)")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun roundingConversion() {
|
||||
assertEquals(1L, 1.0F.roundToLong())
|
||||
assertEquals(1L, 1.1F.roundToLong())
|
||||
assertEquals(2L, 1.5F.roundToLong())
|
||||
assertEquals(3L, 2.5F.roundToLong())
|
||||
assertEquals(-2L, (-2.5F).roundToLong())
|
||||
assertEquals(-3L, (-2.6F).roundToLong())
|
||||
// assertEquals(9223372036854774784, (9223372036854774800.0F).roundToLong()) // platform-specific
|
||||
assertEquals(Long.MAX_VALUE, Float.MAX_VALUE.roundToLong())
|
||||
assertEquals(Long.MIN_VALUE, (-Float.MAX_VALUE).roundToLong())
|
||||
assertEquals(Long.MAX_VALUE, Float.POSITIVE_INFINITY.roundToLong())
|
||||
assertEquals(Long.MIN_VALUE, Float.NEGATIVE_INFINITY.roundToLong())
|
||||
|
||||
assertEquals(1, 1.0F.roundToInt())
|
||||
assertEquals(1, 1.1F.roundToInt())
|
||||
assertEquals(2, 1.5F.roundToInt())
|
||||
assertEquals(3, 2.5F.roundToInt())
|
||||
assertEquals(-2, (-2.5F).roundToInt())
|
||||
assertEquals(-3, (-2.6F).roundToInt())
|
||||
assertEquals(16777218, (16777218F).roundToInt())
|
||||
assertEquals(Int.MAX_VALUE, Float.MAX_VALUE.roundToInt())
|
||||
assertEquals(Int.MIN_VALUE, (-Float.MAX_VALUE).roundToInt())
|
||||
assertEquals(Int.MAX_VALUE, Float.POSITIVE_INFINITY.roundToInt())
|
||||
assertEquals(Int.MIN_VALUE, Float.NEGATIVE_INFINITY.roundToInt())
|
||||
}
|
||||
|
||||
@Test fun absoluteValue() {
|
||||
assertTrue(abs(Float.NaN).isNaN())
|
||||
assertTrue(Float.NaN.absoluteValue.isNaN())
|
||||
|
||||
for (value in listOf(0.0F, Float.MIN_VALUE, 0.1F, 1.0F, 1000.0F, Float.MAX_VALUE, Float.POSITIVE_INFINITY)) {
|
||||
assertEquals(value, value.absoluteValue)
|
||||
assertEquals(value, (-value).absoluteValue)
|
||||
assertEquals(value, abs(value))
|
||||
assertEquals(value, abs(-value))
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun signs() {
|
||||
assertTrue(sign(Float.NaN).isNaN())
|
||||
assertTrue(Float.NaN.sign.isNaN())
|
||||
|
||||
val negatives = listOf(Float.NEGATIVE_INFINITY, -Float.MAX_VALUE, -1.0F, -Float.MIN_VALUE)
|
||||
for (value in negatives) {
|
||||
assertEquals(-1.0F, sign(value))
|
||||
assertEquals(-1.0F, value.sign)
|
||||
}
|
||||
|
||||
val zeroes = listOf(0.0F, -0.0F)
|
||||
for (value in zeroes) {
|
||||
assertEquals(value, sign(value))
|
||||
assertEquals(value, value.sign)
|
||||
}
|
||||
|
||||
|
||||
val positives = listOf(Float.POSITIVE_INFINITY, Float.MAX_VALUE, 1.0F, Float.MIN_VALUE)
|
||||
for (value in positives) {
|
||||
assertEquals(1.0F, sign(value))
|
||||
assertEquals(1.0F, value.sign)
|
||||
}
|
||||
|
||||
val allValues = negatives + positives
|
||||
for (a in allValues) {
|
||||
for (b in allValues) {
|
||||
val r = a.withSign(b)
|
||||
assertEquals(a.absoluteValue, r.absoluteValue)
|
||||
assertEquals(b.sign, r.sign)
|
||||
}
|
||||
|
||||
val rp0 = a.withSign(0.0F)
|
||||
assertEquals(1.0F, rp0.sign)
|
||||
assertEquals(a.absoluteValue, rp0.absoluteValue)
|
||||
|
||||
val rm0 = a.withSign(-0.0F)
|
||||
assertEquals(-1.0F, rm0.sign)
|
||||
assertEquals(a.absoluteValue, rm0.absoluteValue)
|
||||
|
||||
val ri = a.withSign(-1)
|
||||
assertEquals(-1.0F, ri.sign)
|
||||
assertEquals(a.absoluteValue, ri.absoluteValue)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun nextAndPrev() {
|
||||
for (value in listOf(0.0f, -0.0f, Float.MIN_VALUE, -1.0f, 2.0f.pow(10))) {
|
||||
val next = value.nextUp()
|
||||
if (next > 0) {
|
||||
assertEquals(next, value + value.ulp)
|
||||
} else {
|
||||
assertEquals(value, next - next.ulp)
|
||||
}
|
||||
|
||||
val prev = value.nextDown()
|
||||
if (prev > 0) {
|
||||
assertEquals(value, prev + prev.ulp)
|
||||
}
|
||||
else {
|
||||
assertEquals(prev, value - value.ulp)
|
||||
}
|
||||
|
||||
val toZero = value.nextTowards(0.0f)
|
||||
if (toZero != 0.0f) {
|
||||
assertEquals(value, toZero + toZero.ulp.withSign(toZero))
|
||||
}
|
||||
|
||||
assertEquals(Float.POSITIVE_INFINITY, Float.MAX_VALUE.nextUp())
|
||||
assertEquals(Float.MAX_VALUE, Float.POSITIVE_INFINITY.nextDown())
|
||||
|
||||
assertEquals(Float.NEGATIVE_INFINITY, (-Float.MAX_VALUE).nextDown())
|
||||
assertEquals((-Float.MAX_VALUE), Float.NEGATIVE_INFINITY.nextUp())
|
||||
|
||||
assertTrue(Float.NaN.ulp.isNaN())
|
||||
assertTrue(Float.NaN.nextDown().isNaN())
|
||||
assertTrue(Float.NaN.nextUp().isNaN())
|
||||
assertTrue(Float.NaN.nextTowards(0.0f).isNaN())
|
||||
|
||||
assertEquals(Float.MIN_VALUE, (0.0f).ulp)
|
||||
assertEquals(Float.MIN_VALUE, (-0.0f).ulp)
|
||||
assertEquals(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY.ulp)
|
||||
assertEquals(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY.ulp)
|
||||
|
||||
val maxUlp = 2.0f.pow(104)
|
||||
assertEquals(maxUlp, Float.MAX_VALUE.ulp)
|
||||
assertEquals(maxUlp, (-Float.MAX_VALUE).ulp)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun IEEEremainder() {
|
||||
val data = arrayOf( // a a IEEErem 2.5
|
||||
floatArrayOf(-2.0f, 0.5f),
|
||||
floatArrayOf(-1.25f, -1.25f),
|
||||
floatArrayOf( 0.0f, 0.0f),
|
||||
floatArrayOf( 1.0f, 1.0f),
|
||||
floatArrayOf( 1.25f, 1.25f),
|
||||
floatArrayOf( 1.5f, -1.0f),
|
||||
floatArrayOf( 2.0f, -0.5f),
|
||||
floatArrayOf( 2.5f, 0.0f),
|
||||
floatArrayOf( 3.5f, 1.0f),
|
||||
floatArrayOf( 3.75f, -1.25f),
|
||||
floatArrayOf( 4.0f, -1.0f)
|
||||
)
|
||||
for ((a, r) in data) {
|
||||
assertEquals(r, a.IEEErem(2.5f), "($a).IEEErem(2.5f)")
|
||||
}
|
||||
|
||||
assertTrue(Float.NaN.IEEErem(2.5f).isNaN())
|
||||
assertTrue(2.0f.IEEErem(Float.NaN).isNaN())
|
||||
assertTrue(Float.POSITIVE_INFINITY.IEEErem(2.0f).isNaN())
|
||||
assertTrue(2.0f.IEEErem(0.0f).isNaN())
|
||||
assertEquals(PI.toFloat(), PI.toFloat().IEEErem(Float.NEGATIVE_INFINITY))
|
||||
}
|
||||
}
|
||||
|
||||
class IntegerMathTest {
|
||||
|
||||
@Test
|
||||
fun intSigns() {
|
||||
val negatives = listOf(Int.MIN_VALUE, -65536, -1)
|
||||
val positives = listOf(1, 100, 256, Int.MAX_VALUE)
|
||||
negatives.forEach { assertEquals(-1, it.sign) }
|
||||
positives.forEach { assertEquals(1, it.sign) }
|
||||
assertEquals(0, 0.sign)
|
||||
|
||||
(negatives - Int.MIN_VALUE).forEach { assertEquals(-it, it.absoluteValue) }
|
||||
assertEquals(Int.MIN_VALUE, Int.MIN_VALUE.absoluteValue)
|
||||
|
||||
positives.forEach { assertEquals(it, it.absoluteValue) }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun longSigns() {
|
||||
val negatives = listOf(Long.MIN_VALUE, -65536L, -1L)
|
||||
val positives = listOf(1L, 100L, 256L, Long.MAX_VALUE)
|
||||
negatives.forEach { assertEquals(-1, it.sign) }
|
||||
positives.forEach { assertEquals(1, it.sign) }
|
||||
assertEquals(0, 0L.sign)
|
||||
|
||||
(negatives - Long.MIN_VALUE).forEach { assertEquals(-it, it.absoluteValue) }
|
||||
assertEquals(Long.MIN_VALUE, Long.MIN_VALUE.absoluteValue)
|
||||
|
||||
positives.forEach { assertEquals(it, it.absoluteValue) }
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package numbers
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.comparisons.*
|
||||
|
||||
val Double.Companion.values get() = listOf(0.0, NEGATIVE_INFINITY, MIN_VALUE, MAX_VALUE, POSITIVE_INFINITY, NaN)
|
||||
val Float.Companion.values get() = listOf(0.0f, NEGATIVE_INFINITY, MIN_VALUE, MAX_VALUE, POSITIVE_INFINITY, NaN)
|
||||
|
||||
class NaNPropagationTest {
|
||||
|
||||
private fun propagateOf2(f2d: (Double, Double) -> Double,
|
||||
f2f: (Float, Float) -> Float,
|
||||
function: String) {
|
||||
with(Double) {
|
||||
for (d in values) {
|
||||
assertTrue(f2d(d, NaN).isNaN(), "$function($d, NaN)")
|
||||
assertTrue(f2d(NaN, d).isNaN(), "$function(NaN, $d)")
|
||||
}
|
||||
}
|
||||
with(Float) {
|
||||
for (f in values) {
|
||||
assertTrue(f2f(f, NaN).isNaN(), "$function($f, NaN)")
|
||||
assertTrue(f2f(NaN, f).isNaN(), "$function(NaN, $f)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun propagateOf3(f3d: (Double, Double, Double) -> Double,
|
||||
f3f: (Float, Float, Float) -> Float, function: String) {
|
||||
|
||||
with(Double) {
|
||||
for (d in values) {
|
||||
assertTrue(f3d(NaN, d, POSITIVE_INFINITY).isNaN(), "$function(NaN, $d, +inf)")
|
||||
assertTrue(f3d(d, NaN, POSITIVE_INFINITY).isNaN(), "$function($d, NaN, +inf)")
|
||||
assertTrue(f3d(d, POSITIVE_INFINITY, NaN).isNaN(), "$function($d, +inf, NaN)")
|
||||
}
|
||||
}
|
||||
with(Float) {
|
||||
for (f in values) {
|
||||
assertTrue(f3f(NaN, f, POSITIVE_INFINITY).isNaN(), "$function(NaN, $f, +inf)")
|
||||
assertTrue(f3f(f, NaN, POSITIVE_INFINITY).isNaN(), "$function($f, NaN, +inf)")
|
||||
assertTrue(f3f(f, POSITIVE_INFINITY, NaN).isNaN(), "$function($f, +inf, NaN)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun minOf() {
|
||||
propagateOf2(::minOf, ::minOf, "minOf")
|
||||
propagateOf3(::minOf, ::minOf, "minOf")
|
||||
}
|
||||
|
||||
@Test fun maxOf() {
|
||||
propagateOf2(::maxOf, ::maxOf, "maxOf")
|
||||
propagateOf3(::maxOf, ::maxOf, "maxOf")
|
||||
}
|
||||
|
||||
@Test fun arrayMin() {
|
||||
propagateOf2({ a, b -> arrayOf(a, b).min()!! },
|
||||
{ a, b -> arrayOf(a, b).min()!! },
|
||||
"arrayOf().min()")
|
||||
}
|
||||
|
||||
@Test fun arrayMax() {
|
||||
propagateOf2({ a, b -> arrayOf(a, b).max()!! },
|
||||
{ a, b -> arrayOf(a, b).max()!! },
|
||||
"arrayOf().max()")
|
||||
}
|
||||
|
||||
@Test fun primitiveArrayMin() {
|
||||
propagateOf2({ a, b -> doubleArrayOf(a, b).min()!! },
|
||||
{ a, b -> floatArrayOf(a, b).min()!! },
|
||||
"primitiveArrayOf().min()")
|
||||
}
|
||||
|
||||
@Test fun primitiveArrayMax() {
|
||||
propagateOf2({ a, b -> doubleArrayOf(a, b).max()!! },
|
||||
{ a, b -> floatArrayOf(a, b).max()!! },
|
||||
"primitiveArrayOf().max()")
|
||||
}
|
||||
|
||||
@Test fun listMin() {
|
||||
propagateOf2({ a, b -> listOf(a, b).min()!! },
|
||||
{ a, b -> listOf(a, b).min()!! },
|
||||
"listOf().min()")
|
||||
}
|
||||
|
||||
@Test fun listMax() {
|
||||
propagateOf2({ a, b -> listOf(a, b).max()!! },
|
||||
{ a, b -> listOf(a, b).max()!! },
|
||||
"listOf().max()")
|
||||
}
|
||||
|
||||
@Test fun sequenceMin() {
|
||||
propagateOf2({ a, b -> sequenceOf(a, b).min()!! },
|
||||
{ a, b -> sequenceOf(a, b).min()!! },
|
||||
"sequenceOf().min()")
|
||||
}
|
||||
|
||||
@Test fun sequenceMax() {
|
||||
propagateOf2({ a, b -> sequenceOf(a, b).max()!! },
|
||||
{ a, b -> sequenceOf(a, b).max()!! },
|
||||
"sequenceOf().max()")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//@JvmVersion
|
||||
class NaNTotalOrderTest {
|
||||
|
||||
private fun <T : Comparable<T>> totalOrderMinOf2(f2t: (T, T) -> T, function: String) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
with (Double) {
|
||||
assertEquals<Any>(0.0, f2t(0.0 as T, NaN as T), "$function(0, NaN)")
|
||||
assertEquals<Any>(0.0, f2t(NaN as T, 0.0 as T), "$function(NaN, 0)")
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : Comparable<T>> totalOrderMaxOf2(f2t: (T, T) -> T, function: String) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
with (Double) {
|
||||
assertTrue((f2t(0.0 as T, NaN as T) as Double).isNaN(), "$function(0, NaN)")
|
||||
assertTrue((f2t(NaN as T, 0.0 as T) as Double).isNaN(), "$function(NaN, 0)")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun minOfT() {
|
||||
totalOrderMinOf2<Comparable<Any>>(::minOf, "minOf")
|
||||
}
|
||||
@Test fun maxOfT() {
|
||||
totalOrderMaxOf2<Comparable<Any>>(::maxOf, "maxOf")
|
||||
}
|
||||
|
||||
@Test fun arrayTMin() {
|
||||
totalOrderMinOf2<Comparable<Any>>({ a, b -> arrayOf(a, b).min()!! }, "arrayOf().min()")
|
||||
}
|
||||
@Test fun arrayTMax() {
|
||||
totalOrderMaxOf2<Comparable<Any>>({ a, b -> arrayOf(a, b).max()!! }, "arrayOf().max()")
|
||||
}
|
||||
|
||||
|
||||
@Test fun listTMin() {
|
||||
totalOrderMinOf2<Comparable<Any>>({ a, b -> listOf(a, b).min()!! }, "listOf().min()")
|
||||
}
|
||||
@Test fun listTMax() {
|
||||
totalOrderMaxOf2<Comparable<Any>>({ a, b -> listOf(a, b).max()!! }, "listOf().max()")
|
||||
}
|
||||
|
||||
|
||||
@Test fun sequenceTMin() {
|
||||
totalOrderMinOf2<Comparable<Any>>({ a, b -> sequenceOf(a, b).min()!! }, "sequenceOf().min()")
|
||||
}
|
||||
@Test fun sequenceTMax() {
|
||||
totalOrderMaxOf2<Comparable<Any>>({ a, b -> sequenceOf(a, b).max()!! }, "sequenceOf().max()")
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
package test.numbers
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
object NumbersTestConstants {
|
||||
public const val byteMinSucc: Byte = (Byte.MIN_VALUE + 1).toByte()
|
||||
public const val byteMaxPred: Byte = (Byte.MAX_VALUE - 1).toByte()
|
||||
|
||||
public const val shortMinSucc: Short = (Short.MIN_VALUE + 1).toShort()
|
||||
public const val shortMaxPred: Short = (Short.MAX_VALUE - 1).toShort()
|
||||
|
||||
public const val intMinSucc: Int = Int.MIN_VALUE + 1
|
||||
public const val intMaxPred: Int = Int.MAX_VALUE - 1
|
||||
|
||||
public const val longMinSucc: Long = Long.MIN_VALUE + 1L
|
||||
public const val longMaxPred: Long = Long.MAX_VALUE - 1L
|
||||
}
|
||||
|
||||
class NumbersTest {
|
||||
|
||||
var one: Int = 1
|
||||
var oneS: Short = 1
|
||||
var oneB: Byte = 1
|
||||
|
||||
@Test fun intMinMaxValues() {
|
||||
assertTrue(Int.MIN_VALUE < 0)
|
||||
assertTrue(Int.MAX_VALUE > 0)
|
||||
|
||||
assertEquals(NumbersTestConstants.intMinSucc, Int.MIN_VALUE + one)
|
||||
assertEquals(NumbersTestConstants.intMaxPred, Int.MAX_VALUE - one)
|
||||
|
||||
// overflow behavior
|
||||
expect(Int.MIN_VALUE) { Int.MAX_VALUE + one }
|
||||
expect(Int.MAX_VALUE) { Int.MIN_VALUE - one }
|
||||
}
|
||||
|
||||
@Test fun longMinMaxValues() {
|
||||
assertTrue(Long.MIN_VALUE < 0)
|
||||
assertTrue(Long.MAX_VALUE > 0)
|
||||
|
||||
assertEquals(NumbersTestConstants.longMinSucc, Long.MIN_VALUE + one)
|
||||
assertEquals(NumbersTestConstants.longMaxPred, Long.MAX_VALUE - one)
|
||||
|
||||
// overflow behavior
|
||||
expect(Long.MIN_VALUE) { Long.MAX_VALUE + one }
|
||||
expect(Long.MAX_VALUE) { Long.MIN_VALUE - one }
|
||||
}
|
||||
|
||||
@Test fun shortMinMaxValues() {
|
||||
assertTrue(Short.MIN_VALUE < 0)
|
||||
assertTrue(Short.MAX_VALUE > 0)
|
||||
|
||||
assertEquals(NumbersTestConstants.shortMinSucc, Short.MIN_VALUE.inc())
|
||||
assertEquals(NumbersTestConstants.shortMaxPred, Short.MAX_VALUE.dec())
|
||||
|
||||
// overflow behavior
|
||||
expect(Short.MIN_VALUE) { (Short.MAX_VALUE + oneS).toShort() }
|
||||
expect(Short.MAX_VALUE) { (Short.MIN_VALUE - oneS).toShort() }
|
||||
}
|
||||
|
||||
@Test fun byteMinMaxValues() {
|
||||
assertTrue(Byte.MIN_VALUE < 0)
|
||||
assertTrue(Byte.MAX_VALUE > 0)
|
||||
|
||||
assertEquals(NumbersTestConstants.byteMinSucc, Byte.MIN_VALUE.inc())
|
||||
assertEquals(NumbersTestConstants.byteMaxPred, Byte.MAX_VALUE.dec())
|
||||
|
||||
// overflow behavior
|
||||
expect(Byte.MIN_VALUE) { (Byte.MAX_VALUE + oneB).toByte() }
|
||||
expect(Byte.MAX_VALUE) { (Byte.MIN_VALUE - oneB).toByte() }
|
||||
}
|
||||
|
||||
@Test fun doubleMinMaxValues() {
|
||||
assertTrue(Double.MIN_VALUE > 0)
|
||||
assertTrue(Double.MAX_VALUE > 0)
|
||||
|
||||
// overflow behavior
|
||||
expect(Double.POSITIVE_INFINITY) { Double.MAX_VALUE * 2 }
|
||||
expect(Double.NEGATIVE_INFINITY) {-Double.MAX_VALUE * 2 }
|
||||
expect(0.0) { Double.MIN_VALUE / 2 }
|
||||
}
|
||||
|
||||
@Test fun floatMinMaxValues() {
|
||||
assertTrue(Float.MIN_VALUE > 0)
|
||||
assertTrue(Float.MAX_VALUE > 0)
|
||||
|
||||
// overflow behavior
|
||||
expect(Float.POSITIVE_INFINITY) { Float.MAX_VALUE * 2 }
|
||||
expect(Float.NEGATIVE_INFINITY) { -Float.MAX_VALUE * 2 }
|
||||
expect(0.0F) { Float.MIN_VALUE / 2.0F }
|
||||
}
|
||||
|
||||
@Test fun doubleProperties() {
|
||||
for (value in listOf(1.0, 0.0, Double.MIN_VALUE, Double.MAX_VALUE))
|
||||
doTestNumber(value)
|
||||
for (value in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY))
|
||||
doTestNumber(value, isInfinite = true)
|
||||
doTestNumber(Double.NaN, isNaN = true)
|
||||
}
|
||||
|
||||
@Test fun floatProperties() {
|
||||
for (value in listOf(1.0F, 0.0F, Float.MAX_VALUE, Float.MIN_VALUE))
|
||||
doTestNumber(value)
|
||||
for (value in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY))
|
||||
doTestNumber(value, isInfinite = true)
|
||||
doTestNumber(Float.NaN, isNaN = true)
|
||||
}
|
||||
|
||||
|
||||
private fun doTestNumber(value: Double, isNaN: Boolean = false, isInfinite: Boolean = false) {
|
||||
assertEquals(isNaN, value.isNaN(), "Expected $value to have isNaN: $isNaN")
|
||||
assertEquals(isInfinite, value.isInfinite(), "Expected $value to have isInfinite: $isInfinite")
|
||||
assertEquals(!isNaN && !isInfinite, value.isFinite())
|
||||
}
|
||||
|
||||
private fun doTestNumber(value: Float, isNaN: Boolean = false, isInfinite: Boolean = false) {
|
||||
assertEquals(isNaN, value.isNaN(), "Expected $value to have isNaN: $isNaN")
|
||||
assertEquals(isInfinite, value.isInfinite(), "Expected $value to have isInfinite: $isInfinite")
|
||||
assertEquals(!isNaN && !isInfinite, value.isFinite())
|
||||
}
|
||||
|
||||
@Test fun doubleToBits() {
|
||||
assertEquals(0x400921fb54442d18L, kotlin.math.PI.toBits())
|
||||
assertEquals(0x400921fb54442d18L, kotlin.math.PI.toRawBits())
|
||||
assertEquals(kotlin.math.PI, Double.fromBits(0x400921fb54442d18L))
|
||||
|
||||
for (value in listOf(Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, -1.0, -Double.MIN_VALUE, -0.0, 0.0, Double.POSITIVE_INFINITY, Double.MAX_VALUE, 1.0, Double.MIN_VALUE)) {
|
||||
assertEquals(value, Double.fromBits(value.toBits()))
|
||||
assertEquals(value, Double.fromBits(value.toRawBits()))
|
||||
}
|
||||
assertTrue(Double.NaN.toBits().let(Double.Companion::fromBits).isNaN())
|
||||
assertTrue(Double.NaN.toRawBits().let { Double.fromBits(it) }.isNaN())
|
||||
|
||||
assertEquals(0x7FF00000L shl 32, Double.POSITIVE_INFINITY.toBits())
|
||||
assertEquals(0xFFF00000L shl 32, Double.NEGATIVE_INFINITY.toBits())
|
||||
|
||||
assertEquals(0x7FF80000_00000000L, Double.NaN.toBits())
|
||||
assertEquals(0x7FF80000_00000000L, Double.NaN.toRawBits())
|
||||
|
||||
val bitsNaN = Double.NaN.toBits()
|
||||
for (bitsDenormNaN in listOf(0xFFF80000L shl 32, bitsNaN or 1)) {
|
||||
assertTrue(Double.fromBits(bitsDenormNaN).isNaN(), "expected $bitsDenormNaN represent NaN")
|
||||
assertEquals(bitsNaN, Double.fromBits(bitsDenormNaN).toBits())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun floatToBits() {
|
||||
val PI_F = kotlin.math.PI.toFloat()
|
||||
assertEquals(0x40490fdb, PI_F.toBits())
|
||||
assertAlmostEquals(PI_F, Float.fromBits(0x40490fdb)) // PI_F is actually Double in JS
|
||||
// -Float.MAX_VALUE, Float.MAX_VALUE, -Float.MIN_VALUE, Float.MIN_VALUE: overflow or underflow
|
||||
for (value in listOf(Float.NEGATIVE_INFINITY, -1.0F, -0.0F, 0.0F, Float.POSITIVE_INFINITY, 1.0F)) {
|
||||
assertEquals(value, Float.fromBits(value.toBits()))
|
||||
assertEquals(value, Float.fromBits(value.toRawBits()))
|
||||
}
|
||||
|
||||
assertTrue(Float.NaN.toBits().let(Float.Companion::fromBits).isNaN())
|
||||
assertTrue(Float.NaN.toRawBits().let { Float.fromBits(it) }.isNaN())
|
||||
|
||||
assertEquals(0xbf800000.toInt(), (-1.0F).toBits())
|
||||
assertEquals(0x7fc00000, Float.NaN.toBits())
|
||||
assertEquals(0x7fc00000, Float.NaN.toRawBits())
|
||||
|
||||
val bitsNaN = Float.NaN.toBits()
|
||||
for (bitsDenormNaN in listOf(0xFFFC0000.toInt(), bitsNaN or 1)) {
|
||||
assertTrue(Float.fromBits(bitsDenormNaN).isNaN(), "expected $bitsDenormNaN represent NaN")
|
||||
assertEquals(bitsNaN, Float.fromBits(bitsDenormNaN).toBits())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package test.properties.delegation
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.properties.*
|
||||
|
||||
class NotNullVarTest() {
|
||||
@Test fun doTest() {
|
||||
NotNullVarTestGeneric("a", "b").doTest()
|
||||
}
|
||||
}
|
||||
|
||||
private class NotNullVarTestGeneric<T : Any>(val a1: String, val b1: T) {
|
||||
var a: String by Delegates.notNull()
|
||||
var b by Delegates.notNull<T>()
|
||||
|
||||
public fun doTest() {
|
||||
a = a1
|
||||
b = b1
|
||||
assertTrue(a == "a", "fail: a should be a, but was $a")
|
||||
assertTrue(b == "b", "fail: b should be b, but was $b")
|
||||
}
|
||||
}
|
||||
|
||||
class ObservablePropertyTest {
|
||||
var result = false
|
||||
|
||||
var b: Int by Delegates.observable(1, { property, old, new ->
|
||||
assertEquals("b", property.name)
|
||||
if (!result) assertEquals(1, old)
|
||||
result = true
|
||||
assertEquals(new, b, "New value has already been set")
|
||||
})
|
||||
|
||||
@Test fun doTest() {
|
||||
b = 4
|
||||
assertTrue(b == 4, "fail: b != 4")
|
||||
assertTrue(result, "fail: result should be true")
|
||||
}
|
||||
}
|
||||
|
||||
class A(val p: Boolean)
|
||||
|
||||
class VetoablePropertyTest {
|
||||
var result = false
|
||||
var b: A by Delegates.vetoable(A(true), { property, old, new ->
|
||||
assertEquals("b", property.name)
|
||||
assertEquals(old, b, "New value hasn't been set yet")
|
||||
result = new.p == true;
|
||||
result
|
||||
})
|
||||
|
||||
@Test fun doTest() {
|
||||
val firstValue = A(true)
|
||||
b = firstValue
|
||||
assertTrue(b == firstValue, "fail1: b should be firstValue = A(true)")
|
||||
assertTrue(result, "fail2: result should be true")
|
||||
b = A(false)
|
||||
assertTrue(b == firstValue, "fail3: b should be firstValue = A(true)")
|
||||
assertFalse(result, "fail4: result should be false")
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package test.properties.delegation.map
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class ValByMapExtensionsTest {
|
||||
val map: Map<String, String> = hashMapOf("a" to "all", "b" to "bar", "c" to "code")
|
||||
val genericMap = mapOf<String, Any?>("i" to 1, "x" to 1.0)
|
||||
|
||||
val a by map
|
||||
val b: String by map
|
||||
val c: Any by map
|
||||
val d: String? by map
|
||||
val e: String by map.withDefault { "default" }
|
||||
val f: String? by map.withDefault { null }
|
||||
// val n: Int by map // prohibited by type system
|
||||
val i: Int by genericMap
|
||||
val x: Double by genericMap
|
||||
|
||||
|
||||
@Test fun doTest() {
|
||||
assertEquals("all", a)
|
||||
assertEquals("bar", b)
|
||||
assertEquals("code", c)
|
||||
assertEquals("default", e)
|
||||
assertEquals(null, f)
|
||||
assertEquals(1, i)
|
||||
assertEquals(1.0, x)
|
||||
assertFailsWith<NoSuchElementException> { d }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class VarByMapExtensionsTest {
|
||||
val map = hashMapOf<String, Any?>("a" to "all", "b" to null, "c" to 1, "xProperty" to 1.0)
|
||||
val map2: MutableMap<String, CharSequence> = hashMapOf("a2" to "all")
|
||||
|
||||
var a: String by map
|
||||
var b: Any? by map
|
||||
var c: Int by map
|
||||
var d: String? by map
|
||||
var a2: String by map2.withDefault { "empty" }
|
||||
//var x: Int by map2 // prohibited by type system
|
||||
|
||||
@Test fun doTest() {
|
||||
assertEquals("all", a)
|
||||
assertEquals(null, b)
|
||||
assertEquals(1, c)
|
||||
c = 2
|
||||
assertEquals(2, c)
|
||||
assertEquals(2, map["c"])
|
||||
|
||||
assertEquals("all", a2)
|
||||
map2.remove("a2")
|
||||
assertEquals("empty", a2)
|
||||
|
||||
assertFailsWith<NoSuchElementException> { d }
|
||||
map["d"] = null
|
||||
assertEquals(null, d)
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package test.properties.delegation.lazy
|
||||
|
||||
import kotlin.properties.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LazyValTest {
|
||||
var result = 0
|
||||
val a by lazy {
|
||||
++result
|
||||
}
|
||||
|
||||
@Test fun doTest() {
|
||||
a
|
||||
assertTrue(a == 1, "fail: initializer should be invoked only once")
|
||||
}
|
||||
}
|
||||
|
||||
class UnsafeLazyValTest {
|
||||
var result = 0
|
||||
val a by lazy(LazyThreadSafetyMode.NONE) {
|
||||
++result
|
||||
}
|
||||
|
||||
@Test fun doTest() {
|
||||
a
|
||||
assertTrue(a == 1, "fail: initializer should be invoked only once")
|
||||
}
|
||||
}
|
||||
|
||||
class NullableLazyValTest {
|
||||
var resultA = 0
|
||||
var resultB = 0
|
||||
|
||||
val a: Int? by lazy { resultA++; null}
|
||||
val b by lazy { foo() }
|
||||
|
||||
@Test fun doTest() {
|
||||
a
|
||||
b
|
||||
|
||||
assertTrue(a == null, "fail: a should be null")
|
||||
assertTrue(b == null, "fail: b should be null")
|
||||
assertTrue(resultA == 1, "fail: initializer for a should be invoked only once")
|
||||
assertTrue(resultB == 1, "fail: initializer for b should be invoked only once")
|
||||
}
|
||||
|
||||
fun foo(): String? {
|
||||
resultB++
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class UnsafeNullableLazyValTest {
|
||||
var resultA = 0
|
||||
var resultB = 0
|
||||
|
||||
val a: Int? by lazy(LazyThreadSafetyMode.NONE) { resultA++; null}
|
||||
val b by lazy(LazyThreadSafetyMode.NONE) { foo() }
|
||||
|
||||
@Test fun doTest() {
|
||||
a
|
||||
b
|
||||
|
||||
assertTrue(a == null, "fail: a should be null")
|
||||
assertTrue(b == null, "fail: a should be null")
|
||||
assertTrue(resultA == 1, "fail: initializer for a should be invoked only once")
|
||||
assertTrue(resultB == 1, "fail: initializer for b should be invoked only once")
|
||||
}
|
||||
|
||||
fun foo(): String? {
|
||||
resultB++
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class IdentityEqualsIsUsedToUnescapeLazyValTest {
|
||||
var equalsCalled = 0
|
||||
private val a by lazy { ClassWithCustomEquality { equalsCalled++ } }
|
||||
|
||||
@Test fun doTest() {
|
||||
a
|
||||
a
|
||||
assertTrue(equalsCalled == 0, "fail: equals called $equalsCalled times.")
|
||||
}
|
||||
}
|
||||
|
||||
private class ClassWithCustomEquality(private val onEqualsCalled: () -> Unit) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
onEqualsCalled()
|
||||
return super.equals(other)
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
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"
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
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'))
|
||||
}
|
||||
}
|
||||
@@ -1,378 +0,0 @@
|
||||
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 }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package test
|
||||
|
||||
// just a static type check
|
||||
fun <T> assertStaticTypeIs(@Suppress("UNUSED_PARAMETER") value: T) {}
|
||||
@@ -1,191 +0,0 @@
|
||||
package test.text
|
||||
|
||||
import kotlin.text.*
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class RegexTest {
|
||||
|
||||
@Test fun matchResult() {
|
||||
val p = "\\d+".toRegex()
|
||||
val input = "123 456 789"
|
||||
|
||||
assertFalse(input matches p)
|
||||
assertFalse(p matches input)
|
||||
|
||||
assertTrue(p in input)
|
||||
|
||||
val first = p.find(input)
|
||||
assertTrue(first != null); first!!
|
||||
assertEquals("123", first.value)
|
||||
|
||||
val second1 = first.next()!!
|
||||
val second2 = first.next()!!
|
||||
|
||||
assertEquals("456", second1.value)
|
||||
assertEquals(second1.value, second2.value)
|
||||
|
||||
assertEquals("56", p.find(input, startIndex = 5)?.value)
|
||||
|
||||
val last = second1.next()!!
|
||||
assertEquals("789", last.value)
|
||||
|
||||
val noMatch = last.next()
|
||||
assertEquals(null, noMatch)
|
||||
}
|
||||
|
||||
@Test fun matchIgnoreCase() {
|
||||
for (input in listOf("ascii", "shrödinger"))
|
||||
assertTrue(input.toUpperCase().matches(input.toLowerCase().toRegex(RegexOption.IGNORE_CASE)))
|
||||
}
|
||||
|
||||
@Test fun matchSequence() {
|
||||
val input = "123 456 789"
|
||||
val pattern = "\\d+".toRegex()
|
||||
|
||||
val matches = pattern.findAll(input)
|
||||
val values = matches.map { it.value }
|
||||
val expected = listOf("123", "456", "789")
|
||||
assertEquals(expected, values.toList())
|
||||
assertEquals(expected, values.toList(), "running match sequence second time")
|
||||
assertEquals(expected.drop(1), pattern.findAll(input, startIndex = 3).map { it.value }.toList())
|
||||
|
||||
assertEquals(listOf(0..2, 4..6, 8..10), matches.map { it.range }.toList())
|
||||
}
|
||||
|
||||
@Test fun matchAllSequence() {
|
||||
val input = "test"
|
||||
val pattern = ".*".toRegex()
|
||||
val matches = pattern.findAll(input).toList()
|
||||
assertEquals(input, matches[0].value)
|
||||
assertEquals(input, matches.joinToString("") { it.value })
|
||||
assertEquals(2, matches.size)
|
||||
}
|
||||
|
||||
@Test fun matchGroups() {
|
||||
val input = "1a 2b 3c"
|
||||
val pattern = "(\\d)(\\w)".toRegex()
|
||||
|
||||
val matches = pattern.findAll(input).toList()
|
||||
assertTrue(matches.all { it.groups.size == 3 })
|
||||
|
||||
matches[0].let { m ->
|
||||
assertEquals("1a", m.groups[0]?.value)
|
||||
assertEquals("1", m.groups[1]?.value)
|
||||
assertEquals("a", m.groups[2]?.value)
|
||||
|
||||
assertEquals(listOf("1a", "1", "a"), m.groupValues)
|
||||
|
||||
val (g1, g2) = m.destructured
|
||||
assertEquals("1", g1)
|
||||
assertEquals("a", g2)
|
||||
assertEquals(listOf("1", "a"), m.destructured.toList())
|
||||
}
|
||||
|
||||
matches[1].let { m ->
|
||||
assertEquals("2b", m.groups[0]?.value)
|
||||
assertEquals("2", m.groups[1]?.value)
|
||||
assertEquals("b", m.groups[2]?.value)
|
||||
|
||||
assertEquals(listOf("2b", "2", "b"), m.groupValues)
|
||||
|
||||
val (g1, g2) = m.destructured
|
||||
assertEquals("2", g1)
|
||||
assertEquals("b", g2)
|
||||
assertEquals(listOf("2", "b"), m.destructured.toList())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun matchOptionalGroup() {
|
||||
val pattern = "(hi)|(bye)".toRegex(RegexOption.IGNORE_CASE)
|
||||
|
||||
pattern.find("Hi!")!!.let { m ->
|
||||
assertEquals(3, m.groups.size)
|
||||
assertEquals("Hi", m.groups[1]?.value)
|
||||
assertEquals(null, m.groups[2])
|
||||
|
||||
assertEquals(listOf("Hi", "Hi", ""), m.groupValues)
|
||||
|
||||
val (g1, g2) = m.destructured
|
||||
assertEquals("Hi", g1)
|
||||
assertEquals("", g2)
|
||||
assertEquals(listOf("Hi", ""), m.destructured.toList())
|
||||
}
|
||||
|
||||
pattern.find("bye...")!!.let { m ->
|
||||
assertEquals(3, m.groups.size)
|
||||
assertEquals(null, m.groups[1])
|
||||
assertEquals("bye", m.groups[2]?.value)
|
||||
|
||||
assertEquals(listOf("bye", "", "bye"), m.groupValues)
|
||||
|
||||
val (g1, g2) = m.destructured
|
||||
assertEquals("", g1)
|
||||
assertEquals("bye", g2)
|
||||
assertEquals(listOf("", "bye"), m.destructured.toList())
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun matchMultiline() {
|
||||
val regex = "^[a-z]*$".toRegex(setOf(RegexOption.IGNORE_CASE, RegexOption.MULTILINE))
|
||||
val matchedValues = regex.findAll("test\n\nLine").map { it.value }.toList()
|
||||
assertEquals(listOf("test", "", "Line"), matchedValues)
|
||||
}
|
||||
|
||||
|
||||
@Test fun matchEntire() {
|
||||
val regex = "(\\d)(\\w)".toRegex()
|
||||
|
||||
assertNull(regex.matchEntire("1a 2b"))
|
||||
assertNotNull(regex.matchEntire("3c")) { m ->
|
||||
assertEquals("3c", m.value)
|
||||
assertEquals(3, m.groups.size)
|
||||
assertEquals(listOf("3c", "3", "c"), m.groups.map { it!!.value })
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun matchEntireLazyQuantor() {
|
||||
val regex = "a+b+?".toRegex()
|
||||
val input = StringBuilder("aaaabbbb")
|
||||
|
||||
assertEquals("aaaab", regex.find(input)!!.value)
|
||||
assertEquals("aaaabbbb", regex.matchEntire(input)!!.value)
|
||||
}
|
||||
|
||||
@Test fun escapeLiteral() {
|
||||
val literal = """[-\/\\^$*+?.()|[\]{}]"""
|
||||
assertTrue(Regex.fromLiteral(literal).matches(literal))
|
||||
assertTrue(Regex.escape(literal).toRegex().matches(literal))
|
||||
}
|
||||
|
||||
@Test fun replace() {
|
||||
val input = "123-456"
|
||||
val pattern = "(\\d+)".toRegex()
|
||||
assertEquals("(123)-(456)", pattern.replace(input, "($1)"))
|
||||
|
||||
assertEquals("$&-$&", pattern.replace(input, Regex.escapeReplacement("$&")))
|
||||
assertEquals("X-456", pattern.replaceFirst(input, "X"))
|
||||
}
|
||||
|
||||
@Test fun replaceEvaluator() {
|
||||
val input = "/12/456/7890/"
|
||||
val pattern = "\\d+".toRegex()
|
||||
assertEquals("/2/3/4/", pattern.replace(input, { it.value.length.toString() } ))
|
||||
}
|
||||
|
||||
|
||||
@Test fun split() {
|
||||
val input = """
|
||||
some ${"\t"} word
|
||||
split
|
||||
""".trim()
|
||||
|
||||
assertEquals(listOf("some", "word", "split"), "\\s+".toRegex().split(input))
|
||||
|
||||
assertEquals(listOf("name", "value=5"), "=".toRegex().split("name=value=5", limit = 2))
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package test.text
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class StringBuilderTest {
|
||||
|
||||
@Test fun stringBuild() {
|
||||
val s = buildString {
|
||||
append("a")
|
||||
append(true)
|
||||
}
|
||||
assertEquals("atrue", s)
|
||||
}
|
||||
|
||||
@Test fun appendMany() {
|
||||
assertEquals("a1", StringBuilder().append("a", "1").toString())
|
||||
assertEquals("a1", StringBuilder().append("a", 1).toString())
|
||||
assertEquals("a1", StringBuilder().append("a", StringBuilder().append("1")).toString())
|
||||
}
|
||||
|
||||
@Test fun append() {
|
||||
// this test is needed for JS implementation
|
||||
assertEquals("em", buildString {
|
||||
append("element", 2, 4)
|
||||
})
|
||||
}
|
||||
|
||||
@Test fun asCharSequence() {
|
||||
val original = "Some test string"
|
||||
val sb = StringBuilder(original)
|
||||
val result = sb.toString()
|
||||
val cs = sb as CharSequence
|
||||
|
||||
assertEquals(result.length, cs.length)
|
||||
assertEquals(result.length, sb.length)
|
||||
for (index in result.indices) {
|
||||
assertEquals(result[index], sb[index])
|
||||
assertEquals(result[index], cs[index])
|
||||
}
|
||||
assertEquals(result.substring(2, 6), cs.subSequence(2, 6).toString())
|
||||
}
|
||||
|
||||
@Test fun constructors() {
|
||||
StringBuilder().let { sb ->
|
||||
assertEquals(0, sb.length)
|
||||
assertEquals("", sb.toString())
|
||||
}
|
||||
|
||||
StringBuilder(16).let { sb ->
|
||||
assertEquals(0, sb.length)
|
||||
assertEquals("", sb.toString())
|
||||
}
|
||||
|
||||
StringBuilder("content").let { sb ->
|
||||
assertEquals(7, sb.length)
|
||||
assertEquals("content", sb.toString())
|
||||
}
|
||||
|
||||
StringBuilder(StringBuilder("content")).let { sb ->
|
||||
assertEquals(7, sb.length)
|
||||
assertEquals("content", sb.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
package test.text
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class StringNumberConversionTest {
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun toBoolean() {
|
||||
assertEquals(true, "true".toBoolean())
|
||||
assertEquals(true, "True".toBoolean())
|
||||
assertEquals(false, "false".toBoolean())
|
||||
assertEquals(false, "not so true".toBoolean())
|
||||
}
|
||||
|
||||
@Test fun toByte() {
|
||||
compareConversion({it.toByte()}, {it.toByteOrNull()}) {
|
||||
assertProduces("127", Byte.MAX_VALUE)
|
||||
assertProduces("+77", 77.toByte())
|
||||
assertProduces("-128", Byte.MIN_VALUE)
|
||||
assertFailsOrNull("128")
|
||||
assertFailsOrNull("")
|
||||
assertFailsOrNull(" ")
|
||||
}
|
||||
|
||||
compareConversionWithRadix(String::toByte, String::toByteOrNull) {
|
||||
assertProduces(16, "7a", 0x7a.toByte())
|
||||
assertProduces(16, "+7F", 127.toByte())
|
||||
assertProduces(16, "-80", (-128).toByte())
|
||||
assertFailsOrNull(2, "10000000")
|
||||
assertFailsOrNull(8, "")
|
||||
assertFailsOrNull(8, " ")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun toShort() {
|
||||
compareConversion({it.toShort()}, {it.toShortOrNull()}) {
|
||||
assertProduces("+77", 77.toShort())
|
||||
assertProduces("32767", Short.MAX_VALUE)
|
||||
assertProduces("-32768", Short.MIN_VALUE)
|
||||
assertFailsOrNull("+32768")
|
||||
assertFailsOrNull("")
|
||||
assertFailsOrNull(" ")
|
||||
}
|
||||
|
||||
compareConversionWithRadix(String::toShort, String::toShortOrNull) {
|
||||
assertProduces(16, "7FFF", 0x7FFF.toShort())
|
||||
assertProduces(16, "-8000", (-0x8000).toShort())
|
||||
assertFailsOrNull(5, "10000000")
|
||||
assertFailsOrNull(2, "")
|
||||
assertFailsOrNull(2, " ")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun toInt() {
|
||||
compareConversion({it.toInt()}, {it.toIntOrNull()}) {
|
||||
assertProduces("77", 77)
|
||||
assertProduces("+2147483647", Int.MAX_VALUE)
|
||||
assertProduces("-2147483648", Int.MIN_VALUE)
|
||||
|
||||
assertFailsOrNull("2147483648")
|
||||
assertFailsOrNull("-2147483649")
|
||||
assertFailsOrNull("239239kotlin")
|
||||
assertFailsOrNull("")
|
||||
assertFailsOrNull(" ")
|
||||
}
|
||||
|
||||
compareConversionWithRadix(String::toInt, String::toIntOrNull) {
|
||||
assertProduces(10, "0", 0)
|
||||
assertProduces(10, "473", 473)
|
||||
assertProduces(10, "+42", 42)
|
||||
assertProduces(10, "-0", 0)
|
||||
assertProduces(10, "2147483647", 2147483647)
|
||||
assertProduces(10, "-2147483648", -2147483648)
|
||||
|
||||
assertProduces(16, "-FF", -255)
|
||||
assertProduces(16, "-ff", -255)
|
||||
assertProduces(2, "1100110", 102)
|
||||
assertProduces(27, "Kona", 411787)
|
||||
|
||||
assertFailsOrNull(10, "2147483648")
|
||||
assertFailsOrNull(8, "99")
|
||||
assertFailsOrNull(10, "Kona")
|
||||
assertFailsOrNull(16, "")
|
||||
assertFailsOrNull(16, " ")
|
||||
}
|
||||
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 1") { "1".toInt(radix = 1) }
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 37") { "37".toIntOrNull(radix = 37) }
|
||||
}
|
||||
|
||||
//@JvmVersion
|
||||
@Test fun toIntArabicDigits() {
|
||||
compareConversion({ it.toInt() }, { it.toIntOrNull() }) {
|
||||
assertProduces("٢٣١٩٦٠", 231960)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun toLong() {
|
||||
compareConversion({it.toLong()}, {it.toLongOrNull()}) {
|
||||
assertProduces("77", 77.toLong())
|
||||
assertProduces("+9223372036854775807", Long.MAX_VALUE)
|
||||
assertProduces("-9223372036854775808", Long.MIN_VALUE)
|
||||
|
||||
assertFailsOrNull("9223372036854775808")
|
||||
assertFailsOrNull("-9223372036854775809")
|
||||
assertFailsOrNull("922337 75809")
|
||||
assertFailsOrNull("92233,75809")
|
||||
assertFailsOrNull("92233`75809")
|
||||
assertFailsOrNull("-922337KOTLIN775809")
|
||||
assertFailsOrNull("")
|
||||
assertFailsOrNull(" ")
|
||||
}
|
||||
|
||||
compareConversionWithRadix(String::toLong, String::toLongOrNull) {
|
||||
assertProduces(10, "0", 0L)
|
||||
assertProduces(10, "473", 473L)
|
||||
assertProduces(10, "+42", 42L)
|
||||
assertProduces(10, "-0", 0L)
|
||||
|
||||
assertProduces(16, "7F11223344556677", 0x7F11223344556677)
|
||||
assertProduces(16, "+7faabbccddeeff00", 0x7faabbccddeeff00)
|
||||
assertProduces(16, "-8000000000000000", Long.MIN_VALUE)
|
||||
assertProduces(2, "1100110", 102L)
|
||||
assertProduces(36, "Hazelnut", 1356099454469L)
|
||||
|
||||
assertFailsOrNull(8, "99")
|
||||
assertFailsOrNull(10, "Hazelnut")
|
||||
assertFailsOrNull(4, "")
|
||||
assertFailsOrNull(4, " ")
|
||||
}
|
||||
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 37") { "37".toLong(radix = 37) }
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 1") { "1".toLongOrNull(radix = 1) }
|
||||
}
|
||||
|
||||
//@JvmVersion
|
||||
@Test fun toLongArabicDigits() {
|
||||
compareConversion({ it.toLong() }, { it.toLongOrNull() }) {
|
||||
assertProduces("٢٣١٩٦٠٧٧٨٤٥٩", 231960778459)
|
||||
}
|
||||
}
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun toFloat() {
|
||||
compareConversion(String::toFloat, String::toFloatOrNull) {
|
||||
assertProduces("77.0", 77.0f)
|
||||
assertProduces("-1e39", Float.NEGATIVE_INFINITY)
|
||||
assertProduces("1000000000000000000000000000000000000000", Float.POSITIVE_INFINITY)
|
||||
assertFailsOrNull("dark side")
|
||||
assertFailsOrNull("")
|
||||
assertFailsOrNull(" ")
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun toDouble() {
|
||||
compareConversion(String::toDouble, String::toDoubleOrNull, ::doubleEquals) {
|
||||
assertProduces("-77", -77.0)
|
||||
assertProduces("77.", 77.0)
|
||||
assertProduces("77.0", 77.0)
|
||||
assertProduces("-1.77", -1.77)
|
||||
assertProduces("+.77", 0.77)
|
||||
assertProduces("\t-77 \n", -77.0)
|
||||
assertProduces("7.7e1", 77.0)
|
||||
assertProduces("+770e-1", 77.0)
|
||||
|
||||
assertProduces("-NaN", -Double.NaN)
|
||||
assertProduces("+Infinity", Double.POSITIVE_INFINITY)
|
||||
|
||||
assertFailsOrNull("7..7")
|
||||
assertFailsOrNull("007 not a number")
|
||||
assertFailsOrNull("")
|
||||
assertFailsOrNull(" ")
|
||||
}
|
||||
}
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun toHexDouble() {
|
||||
compareConversion(String::toDouble, String::toDoubleOrNull, ::doubleEquals) {
|
||||
assertProduces("0x77p1", (0x77 shl 1).toDouble())
|
||||
assertProduces("0x.77P8", 0x77.toDouble())
|
||||
|
||||
assertFailsOrNull("0x77e1")
|
||||
}
|
||||
}
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun byteToStringWithRadix() {
|
||||
assertEquals("7a", 0x7a.toByte().toString(16))
|
||||
assertEquals("-80", Byte.MIN_VALUE.toString(radix = 16))
|
||||
assertEquals("3v", Byte.MAX_VALUE.toString(radix = 32))
|
||||
assertEquals("-40", Byte.MIN_VALUE.toString(radix = 32))
|
||||
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 37") { 37.toByte().toString(radix = 37) }
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 1") { 1.toByte().toString(radix = 1) }
|
||||
}
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun shortToStringWithRadix() {
|
||||
assertEquals("7FFF", 0x7FFF.toShort().toString(radix = 16).toUpperCase())
|
||||
assertEquals("-8000", (-0x8000).toShort().toString(radix = 16))
|
||||
assertEquals("-sfs", (-29180).toShort().toString(radix = 32))
|
||||
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 37") { 37.toShort().toString(radix = 37) }
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 1") { 1.toShort().toString(radix = 1) }
|
||||
}
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun intToStringWithRadix() {
|
||||
assertEquals("-ff", (-255).toString(radix = 16))
|
||||
assertEquals("1100110", 102.toString(radix = 2))
|
||||
assertEquals("kona", 411787.toString(radix = 27))
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 37") { 37.toString(radix = 37) }
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 1") { 1.toString(radix = 1) }
|
||||
|
||||
}
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun longToStringWithRadix() {
|
||||
assertEquals("7f11223344556677", 0x7F11223344556677.toString(radix = 16))
|
||||
assertEquals("hazelnut", 1356099454469L.toString(radix = 36))
|
||||
assertEquals("-8000000000000000", Long.MIN_VALUE.toString(radix = 16))
|
||||
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 37") { 37L.toString(radix = 37) }
|
||||
assertFailsWith<IllegalArgumentException>("Expected to fail with radix 1") { 1L.toString(radix = 1) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun <T : Any> compareConversion(convertOrFail: (String) -> T,
|
||||
convertOrNull: (String) -> T?,
|
||||
equality: (T, T?) -> Boolean = { a, b -> a == b },
|
||||
assertions: ConversionContext<T>.() -> Unit) {
|
||||
ConversionContext(convertOrFail, convertOrNull, equality).assertions()
|
||||
}
|
||||
|
||||
|
||||
private fun <T : Any> compareConversionWithRadix(convertOrFail: String.(Int) -> T,
|
||||
convertOrNull: String.(Int) -> T?,
|
||||
assertions: ConversionWithRadixContext<T>.() -> Unit) {
|
||||
ConversionWithRadixContext(convertOrFail, convertOrNull).assertions()
|
||||
}
|
||||
|
||||
|
||||
private class ConversionContext<T: Any>(val convertOrFail: (String) -> T,
|
||||
val convertOrNull: (String) -> T?,
|
||||
val equality: (T, T?) -> Boolean) {
|
||||
|
||||
private fun assertEquals(expected: T, actual: T?, input: String, operation: String) {
|
||||
assertTrue(equality(expected, actual), "Expected $operation('$input') to produce $expected but was $actual")
|
||||
}
|
||||
|
||||
fun assertProduces(input: String, output: T) {
|
||||
assertEquals(output, convertOrFail(input), input, "convertOrFail")
|
||||
assertEquals(output, convertOrNull(input), input, "convertOrNull")
|
||||
}
|
||||
|
||||
fun assertFailsOrNull(input: String) {
|
||||
assertFailsWith<NumberFormatException>("Expected to fail on input \"$input\"") { convertOrFail(input) }
|
||||
assertNull(convertOrNull(input), message = "On input \"$input\"")
|
||||
}
|
||||
}
|
||||
|
||||
private class ConversionWithRadixContext<T: Any>(val convertOrFail: (String, Int) -> T,
|
||||
val convertOrNull: (String, Int) -> T?) {
|
||||
fun assertProduces(radix: Int, input: String, output: T) {
|
||||
assertEquals(output, convertOrFail(input, radix))
|
||||
assertEquals(output, convertOrNull(input, radix))
|
||||
}
|
||||
|
||||
fun assertFailsOrNull(radix: Int, input: String) {
|
||||
assertFailsWith<NumberFormatException>("Expected to fail on input \"$input\" with radix $radix",
|
||||
{ convertOrFail(input, radix) })
|
||||
|
||||
assertNull(convertOrNull(input, radix), message = "On input \"$input\" with radix $radix")
|
||||
}
|
||||
}
|
||||
|
||||
private fun doubleEquals(a: Double, b: Double?) = (a.isNaN() && b?.isNaN() ?: false) || a == b
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +0,0 @@
|
||||
package test.utils
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
|
||||
class KotlinVersionTest {
|
||||
|
||||
@Test fun currentVersion() {
|
||||
assertTrue(KotlinVersion.CURRENT.isAtLeast(1, 1))
|
||||
assertTrue(KotlinVersion.CURRENT.isAtLeast(1, 1, 0))
|
||||
assertTrue(KotlinVersion.CURRENT >= KotlinVersion(1, 1))
|
||||
assertTrue(KotlinVersion(1, 1) <= KotlinVersion.CURRENT)
|
||||
|
||||
val anotherCurrent = KotlinVersion.CURRENT.run { KotlinVersion(major, minor, patch) }
|
||||
assertEquals(KotlinVersion.CURRENT, anotherCurrent)
|
||||
assertEquals(KotlinVersion.CURRENT.hashCode(), anotherCurrent.hashCode())
|
||||
assertEquals(0, KotlinVersion.CURRENT.compareTo(anotherCurrent))
|
||||
}
|
||||
|
||||
@Test fun componentValidation() {
|
||||
for (component in listOf(Int.MIN_VALUE, -1, 0, KotlinVersion.MAX_COMPONENT_VALUE, KotlinVersion.MAX_COMPONENT_VALUE + 1, Int.MAX_VALUE)) {
|
||||
for (place in 0..2) {
|
||||
val (major, minor, patch) = IntArray(3) { index -> if (index == place) component else 0 }
|
||||
if (component in 0..KotlinVersion.MAX_COMPONENT_VALUE) {
|
||||
KotlinVersion(major, minor, patch)
|
||||
}
|
||||
else {
|
||||
assertFailsWith<IllegalArgumentException>("Expected $major.$minor.$patch to be invalid version") {
|
||||
KotlinVersion(major, minor, patch)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun versionComparison() {
|
||||
val v100 = KotlinVersion(1, 0, 0)
|
||||
val v107 = KotlinVersion(1, 0, 7)
|
||||
val v110 = KotlinVersion(1, 1, 0)
|
||||
val v114 = KotlinVersion(1, 1, 4)
|
||||
val v115 = KotlinVersion(1, 1, 50)
|
||||
val v120 = KotlinVersion(1, 2, 0)
|
||||
val v122 = KotlinVersion(1, 2, 20)
|
||||
val v2 = KotlinVersion(2, 0, 0)
|
||||
|
||||
val sorted = listOf(v100, v107, v110, v114, v115, v120, v122, v2)
|
||||
for ((prev, next) in sorted.zip(sorted.drop(1))) { // use zipWithNext in 1.2
|
||||
val message = "next: $next, prev: $prev"
|
||||
assertTrue(next > prev, message)
|
||||
assertTrue(next.isAtLeast(prev.major, prev.minor, prev.patch), message)
|
||||
assertTrue(next.isAtLeast(prev.major, prev.minor), message)
|
||||
assertTrue(next.isAtLeast(next.major, next.minor, next.patch), message)
|
||||
assertTrue(next.isAtLeast(next.major, next.minor), message)
|
||||
assertFalse(prev.isAtLeast(next.major, next.minor, next.patch), message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package test.utils
|
||||
|
||||
import kotlin.*
|
||||
import kotlin.test.*
|
||||
|
||||
class LazyTest {
|
||||
|
||||
@Test fun initializationCalledOnce() {
|
||||
var callCount = 0
|
||||
val lazyInt = lazy { ++callCount }
|
||||
|
||||
assertEquals(0, callCount)
|
||||
assertFalse(lazyInt.isInitialized())
|
||||
assertEquals(1, lazyInt.value)
|
||||
assertEquals(1, callCount)
|
||||
assertTrue(lazyInt.isInitialized())
|
||||
|
||||
lazyInt.value
|
||||
assertEquals(1, callCount)
|
||||
}
|
||||
|
||||
@Test fun alreadyInitialized() {
|
||||
val lazyInt = lazyOf(1)
|
||||
|
||||
assertTrue(lazyInt.isInitialized())
|
||||
assertEquals(1, lazyInt.value)
|
||||
}
|
||||
|
||||
|
||||
@Test fun lazyToString() {
|
||||
var callCount = 0
|
||||
val lazyInt = lazy { ++callCount }
|
||||
|
||||
assertNotEquals("1", lazyInt.toString())
|
||||
assertEquals(0, callCount)
|
||||
|
||||
assertEquals(1, lazyInt.value)
|
||||
assertEquals("1", lazyInt.toString())
|
||||
assertEquals(1, callCount)
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
package test.utils
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
class PreconditionsTest() {
|
||||
|
||||
@Test fun passingRequire() {
|
||||
require(true)
|
||||
|
||||
var called = false
|
||||
require(true) { called = true; "some message" }
|
||||
assertFalse(called)
|
||||
}
|
||||
|
||||
@Test fun failingRequire() {
|
||||
val error = assertFailsWith<IllegalArgumentException> {
|
||||
require(false)
|
||||
}
|
||||
assertNotNull(error.message)
|
||||
}
|
||||
|
||||
@Test fun failingRequireWithLazyMessage() {
|
||||
val error = assertFailsWith<IllegalArgumentException> {
|
||||
require(false) { "Hello" }
|
||||
}
|
||||
assertEquals("Hello", error.message)
|
||||
}
|
||||
|
||||
@Test fun passingCheck() {
|
||||
check(true)
|
||||
|
||||
var called = false
|
||||
check(true) { called = true; "some message" }
|
||||
assertFalse(called)
|
||||
}
|
||||
|
||||
@Test fun failingCheck() {
|
||||
val error = assertFailsWith<IllegalStateException> {
|
||||
check(false)
|
||||
}
|
||||
assertNotNull(error.message)
|
||||
}
|
||||
|
||||
@Test fun failingCheckWithLazyMessage() {
|
||||
val error = assertFailsWith<IllegalStateException> {
|
||||
check(false) { "Hello" }
|
||||
}
|
||||
assertEquals("Hello", error.message)
|
||||
}
|
||||
|
||||
@Test fun requireNotNull() {
|
||||
val s1: String? = "S1"
|
||||
val r1: String = requireNotNull(s1)
|
||||
assertEquals("S1", r1)
|
||||
}
|
||||
|
||||
@Test fun requireNotNullFails() {
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val s2: String? = null
|
||||
requireNotNull(s2)
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun requireNotNullWithLazyMessage() {
|
||||
val error = assertFailsWith<IllegalArgumentException> {
|
||||
val obj: Any? = null
|
||||
requireNotNull(obj) { "Message" }
|
||||
}
|
||||
assertEquals("Message", error.message)
|
||||
|
||||
var lazyCalled: Boolean = false
|
||||
requireNotNull("not null") {
|
||||
lazyCalled = true
|
||||
"Message"
|
||||
}
|
||||
assertFalse(lazyCalled, "Message is not evaluated if the condition is met")
|
||||
}
|
||||
|
||||
@Test fun checkNotNull() {
|
||||
val s1: String? = "S1"
|
||||
val r1: String = checkNotNull(s1)
|
||||
assertEquals("S1", r1)
|
||||
}
|
||||
|
||||
@Test fun checkNotNullFails() {
|
||||
assertFailsWith<IllegalStateException> {
|
||||
val s2: String? = null
|
||||
checkNotNull(s2)
|
||||
}
|
||||
}
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun passingAssert() {
|
||||
assert(true)
|
||||
var called = false
|
||||
assert(true) { called = true; "some message" }
|
||||
|
||||
assertFalse(called)
|
||||
}
|
||||
|
||||
|
||||
//@kotlin.jvm.JvmVersion
|
||||
@Test fun failingAssert() {
|
||||
val error = assertFailsWith<AssertionError> {
|
||||
assert(false)
|
||||
}
|
||||
assertEquals("Assertion failed", error.message)
|
||||
}
|
||||
|
||||
|
||||
// TODO: Uncomment. Disbled due to a serialization bug with assertFailsWith
|
||||
//@kotlin.jvm.JvmVersion
|
||||
//@Test fun failingAssertWithMessage() {
|
||||
// val error = assertFailsWith<AssertionError> {
|
||||
// assert(false) { "Hello" }
|
||||
// }
|
||||
// assertEquals("Hello", error.message)
|
||||
//}
|
||||
|
||||
@Test fun error() {
|
||||
val error = assertFailsWith<IllegalStateException> {
|
||||
error("There was a problem")
|
||||
}
|
||||
assertEquals("There was a problem", error.message)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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 test.utils
|
||||
|
||||
import kotlin.*
|
||||
import kotlin.test.*
|
||||
|
||||
class TODOTest {
|
||||
private class PartiallyImplementedClass {
|
||||
public val prop: String get() = TODO()
|
||||
@Suppress("UNREACHABLE_CODE", "CAST_NEVER_SUCCEEDS")
|
||||
fun method1() = TODO() as String
|
||||
public fun method2(): Int = TODO()
|
||||
|
||||
public fun method3(switch: Boolean, value: String): String {
|
||||
if (!switch)
|
||||
TODO("what if false")
|
||||
else {
|
||||
if (value.length < 3)
|
||||
throw TODO("write message")
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
public fun method4() {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertNotImplemented(block: () -> Unit) {
|
||||
assertFailsWith<NotImplementedError>(block = block)
|
||||
}
|
||||
|
||||
private fun assertNotImplementedWithMessage(message: String, block: () -> Unit) {
|
||||
val e = assertFailsWith<NotImplementedError>(block = block)
|
||||
assertTrue(message in e.message!!)
|
||||
}
|
||||
|
||||
|
||||
@Test fun usage() {
|
||||
val inst = PartiallyImplementedClass()
|
||||
|
||||
assertNotImplemented { inst.prop }
|
||||
assertNotImplemented{ inst.method1() }
|
||||
assertNotImplemented { inst.method2() }
|
||||
assertNotImplemented { inst.method4() }
|
||||
assertNotImplementedWithMessage("what if false") { inst.method3(false, "test") }
|
||||
assertNotImplementedWithMessage("write message") { inst.method3(true, "t") }
|
||||
assertEquals("test", inst.method3(true, "test"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user