From 133afa8327f77af4d27c0bdba6b26b4dbb742816 Mon Sep 17 00:00:00 2001 From: James Strachan Date: Tue, 27 Mar 2012 12:26:20 +0100 Subject: [PATCH] link more documentation to test cases and filled out the test cases a little --- .../jetbrains/kotlin/doc/model/KotlinModel.kt | 8 ++- libraries/stdlib/src/kotlin/Arrays.kt | 11 ++++ .../stdlib/src/kotlin/JavaCollections.kt | 6 +- .../stdlib/src/kotlin/JavaIterablesLazy.kt | 26 ++++++-- .../stdlib/src/kotlin/JavaIterablesSpecial.kt | 7 ++- libraries/stdlib/src/kotlin/JavaUtilMap.kt | 14 ++++- libraries/stdlib/src/kotlin/String.kt | 4 ++ libraries/stdlib/test/CollectionTest.kt | 60 ++++++++++--------- libraries/stdlib/test/MapTest.kt | 28 ++++----- 9 files changed, 106 insertions(+), 58 deletions(-) diff --git a/libraries/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt b/libraries/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt index ea82b54ff89..bdb9dc44242 100644 --- a/libraries/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt +++ b/libraries/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt @@ -391,6 +391,9 @@ class KModel(var context: BindingContext, val config: KDocConfig) { if (remaining.startsWith(macro)) { val next = remaining.substring(macro.length()).trim() val words = next.split("\\s") + // TODO we could default the test function name to match that of the + // source code function if folks adopted a convention of naming the test method after the + // method its acting as a demo/test for if (words != null && words.size > 1) { val includeFile = words[0].sure() val fnName = words[1].sure() @@ -398,9 +401,10 @@ class KModel(var context: BindingContext, val config: KDocConfig) { if (content != null) { // TODO ideally we'd use pygmentize or somehting here to format the Kotlin code... text = "
" + content + "
\n" + } else { + warning("could not find function $fnName in file $includeFile from source file ${psiElement.getContainingFile()}") } - //println("===== included file $includeFile function $fnName as content $content") - } + } } } buffer.append(text) diff --git a/libraries/stdlib/src/kotlin/Arrays.kt b/libraries/stdlib/src/kotlin/Arrays.kt index 2fde990771c..ff488a3a81b 100644 --- a/libraries/stdlib/src/kotlin/Arrays.kt +++ b/libraries/stdlib/src/kotlin/Arrays.kt @@ -4,6 +4,8 @@ import java.io.ByteArrayInputStream import java.util.Arrays import java.nio.charset.Charset +import java.util.List +import java.util.ArrayList // Array "constructor" inline fun array(vararg t : T) : Array = t @@ -121,3 +123,12 @@ inline fun Array.isEmpty() : Boolean = this.size == 0 /** Returns the array if its not null or else returns an empty array */ inline fun Array?.orEmpty() : Array = if (this != null) this else array() +inline fun CharArray.toList(): List { + val list = ArrayList(this.size) + for (c in this) { + if (c != null) { + list.add(Character(c)) + } + } + return list +} \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/JavaCollections.kt b/libraries/stdlib/src/kotlin/JavaCollections.kt index 3cf81d789fe..bea1097e106 100644 --- a/libraries/stdlib/src/kotlin/JavaCollections.kt +++ b/libraries/stdlib/src/kotlin/JavaCollections.kt @@ -2,7 +2,11 @@ package kotlin import java.util.* -/** Returns a new List containing the results of applying the given function to each element in this collection */ +/** + * Returns a new List containing the results of applying the given function to each element in this collection + * + * @includeFunction ../../test/CollectionTest.kt map + */ inline fun java.util.Collection.map(transform : (T) -> R) : java.util.List { return mapTo(java.util.ArrayList(this.size), transform) } diff --git a/libraries/stdlib/src/kotlin/JavaIterablesLazy.kt b/libraries/stdlib/src/kotlin/JavaIterablesLazy.kt index a0068efd98a..72365a73569 100644 --- a/libraries/stdlib/src/kotlin/JavaIterablesLazy.kt +++ b/libraries/stdlib/src/kotlin/JavaIterablesLazy.kt @@ -9,19 +9,33 @@ import java.util.* // See [[GenerateStandardLib.kt]] for more details // -/** Returns a new List containing all elements in this collection which match the given predicate */ +/** + * Returns a new List containing all elements in this collection which match the given predicate + * + * @includeFunction ../../test/CollectionTest.kt filter + */ inline fun java.lang.Iterable.filter(predicate: (T)-> Boolean) : Collection = filterTo(java.util.ArrayList(), predicate) -/** Returns a List containing all the non null elements in this collection */ +/** + * Returns a List containing all the non null elements in this collection + * + * @includeFunction ../../test/CollectionTest.kt filterNotNull + */ inline fun java.lang.Iterable?.filterNotNull() : Collection = filterNotNullTo>(java.util.ArrayList()) -/** Returns a new collection containing all elements in this collection which do not match the given predicate */ +/** + * Returns a new collection containing all elements in this collection which do not match the given predicate + * + * @includeFunction ../../test/CollectionTest.kt filterNot + */ inline fun java.lang.Iterable.filterNot(predicate: (T)-> Boolean) : Collection = filterNotTo(ArrayList(), predicate) /** - * Returns the result of transforming each item in the collection to a one or more values which - * are concatenated together into a single collection - */ + * Returns the result of transforming each item in the collection to a one or more values which + * are concatenated together into a single collection + * + * @includeFunction ../../test/CollectionTest.kt flatMap + */ inline fun java.lang.Iterable.flatMap(transform: (T)-> Collection) : Collection { return flatMapTo(ArrayList(), transform) } diff --git a/libraries/stdlib/src/kotlin/JavaIterablesSpecial.kt b/libraries/stdlib/src/kotlin/JavaIterablesSpecial.kt index bc50003e38b..71a10cf31e4 100644 --- a/libraries/stdlib/src/kotlin/JavaIterablesSpecial.kt +++ b/libraries/stdlib/src/kotlin/JavaIterablesSpecial.kt @@ -28,8 +28,8 @@ fun java.lang.Iterable.count() : Int { * Get the first element in the collection. * * Will throw an exception if there are no elements - * TODO: Specify type of the exception */ +// TODO: Specify type of the exception inline fun java.lang.Iterable.first() : T { if (this is AbstractList) { return this.get(0) @@ -46,8 +46,10 @@ inline fun java.lang.Iterable.first() : T { * last item by iterating through the all items. * * Will throw an exception if there are no elements. - * TODO: Specify type of the exception + * + * @includeFunction ../../test/CollectionTest.kt last */ +// TODO: Specify type of the exception fun java.lang.Iterable.last() : T { if (this is List) { return this.get(this.size() - 1); @@ -71,7 +73,6 @@ fun java.lang.Iterable.last() : T { * method will be used. */ fun java.lang.Iterable.contains(item : T) : Boolean { - kotlin.io.println("!!!!!") if (this is java.util.AbstractCollection) { return this.contains(item); } diff --git a/libraries/stdlib/src/kotlin/JavaUtilMap.kt b/libraries/stdlib/src/kotlin/JavaUtilMap.kt index dbe62e5df1e..079b87a3278 100644 --- a/libraries/stdlib/src/kotlin/JavaUtilMap.kt +++ b/libraries/stdlib/src/kotlin/JavaUtilMap.kt @@ -20,7 +20,7 @@ val JMap<*,*>.empty : Boolean /** Provides [] access to maps */ fun JMap.set(key : K, value : V) = this.put(key, value) -/** Returns the Mao if its not null otherwise it returns the empty Map */ +/** Returns the [[Map]] if its not null otherwise it returns the empty [[Map]] */ inline fun java.util.Map?.orEmpty() : java.util.Map = if (this != null) this else Collections.EMPTY_MAP as java.util.Map @@ -35,7 +35,11 @@ inline fun java.util.Map?.orEmpty() : java.util.Map //val JEntry.value : V // get() = getValue().sure() -/** Returns the value for the given key or returns the result of the defaultValue function if there was no entry for the given key */ +/** + * Returns the value for the given key or returns the result of the defaultValue function if there was no entry for the given key + * + * @includeFunction ../../test/MapTest.kt getOrElse + */ inline fun java.util.Map.getOrElse(key: K, defaultValue: ()-> V) : V { val current = this.get(key) if (current != null) { @@ -45,7 +49,11 @@ inline fun java.util.Map.getOrElse(key: K, defaultValue: ()-> V) : V } } -/** Returns the value for the given key or the result of the defaultValue function is put into the map for the given value and returned */ +/** + * Returns the value for the given key or the result of the defaultValue function is put into the map for the given value and returned + * + * @includeFunction ../../test/MapTest.kt getOrElse + */ inline fun java.util.Map.getOrPut(key: K, defaultValue: ()-> V) : V { val current = this.get(key) if (current != null) { diff --git a/libraries/stdlib/src/kotlin/String.kt b/libraries/stdlib/src/kotlin/String.kt index a9ff87cdeb5..2e678dc9d0f 100644 --- a/libraries/stdlib/src/kotlin/String.kt +++ b/libraries/stdlib/src/kotlin/String.kt @@ -1,6 +1,8 @@ package kotlin import java.io.StringReader +import java.util.List +import java.util.ArrayList inline fun String.lastIndexOf(str: String) = (this as java.lang.String).lastIndexOf(str) @@ -52,6 +54,8 @@ inline fun String.getBytes() = (this as java.lang.String).getBytes().sure() inline fun String.toCharArray() = (this as java.lang.String).toCharArray().sure() +inline fun String.toCharList(): List = toCharArray().toList() + inline fun String.format(format : String, vararg args : Any?) = java.lang.String.format(format, args).sure() inline fun String.split(regex : String) = (this as java.lang.String).split(regex) diff --git a/libraries/stdlib/test/CollectionTest.kt b/libraries/stdlib/test/CollectionTest.kt index 2372ec5b1cb..1e38889e780 100644 --- a/libraries/stdlib/test/CollectionTest.kt +++ b/libraries/stdlib/test/CollectionTest.kt @@ -100,6 +100,18 @@ class CollectionTest { } } + Test fun filterNotNull() { + val data = arrayList(null, "foo", null, "bar") + val foo = data.filterNotNull() + + assertEquals(2, foo.size) + assertEquals(linkedList("foo", "bar"), foo) + + assertTrue { + foo is List + } + } + Test fun filterIntoSet() { val data = arrayList("foo", "bar") // TODO would be nice to avoid the @@ -141,19 +153,12 @@ class CollectionTest { } Test fun flatMap() { - val data = arrayList("foo", "bar") - val characters = arrayList('f', 'o', 'o', 'b', 'a', 'r') - // TODO figure out how to get a line like this to compile :) - /* - val characters = data.flatMap{ - it.toCharArray().toList() as Collection - } - */ - todo { - println("Got list of characters ${characters}") - val text = characters.join("") - assertEquals("foobar", text) - } + val data = arrayList("", "foo", "bar", "x", "") + val characters = data.flatMap{ it.toCharList() } + println("Got list of characters ${characters}") + assertEquals(7, characters.size()) + val text = characters.join("") + assertEquals("foobarx", text) } Test fun forEach() { @@ -165,13 +170,13 @@ class CollectionTest { /* - // TODO would be nice to be able to write this as this - //numbers.fold(0){it + it2} - numbers.fold(0){(it, it2) -> it + it2} + // TODO would be nice to be able to write this as this + //numbers.fold(0){it + it2} + numbers.fold(0){(it, it2) -> it + it2} - // TODO would be nice to be able to write this as this - // numbers.map{it.toString()}.fold(""){it + it2} - numbers.map{it.toString()}.fold(""){(it, it2) -> it + it2} + // TODO would be nice to be able to write this as this + // numbers.map{it.toString()}.fold(""){it + it2} + numbers.map{it.toString()}.fold(""){(it, it2) -> it + it2} */ Test fun fold() { // lets calculate the sum of some numbers @@ -204,7 +209,6 @@ class CollectionTest { } } - /* TODO inference engine should not need this type info? val byLength = words.groupBy{it.length} @@ -225,14 +229,14 @@ class CollectionTest { assertEquals("", text) } + /* + TODO compiler bug + we should be able to remove the explicit type on the map function + http://youtrack.jetbrains.net/issue/KT-1145 + */ Test fun map() { val data = arrayList("foo", "bar") - /** - TODO compiler bug - we should be able to remove the explicit type on the function - http://youtrack.jetbrains.net/issue/KT-1145 - */ - val lengths = data.map{s -> s.length} + val lengths = data.map{ it.length } assertTrue { lengths.all{it == 3} } @@ -281,9 +285,11 @@ class CollectionTest { val data = arrayList("foo", "bar") assertEquals("bar", data.last()) assertEquals(25, arrayList(15, 19, 20, 25).last()) - // assertEquals(19, TreeSet(arrayList(90, 47, 19)).first()) assertEquals('a', linkedList('a').last()) } + // TODO + // assertEquals(19, TreeSet(arrayList(90, 47, 19)).first()) + Test fun lastException() { fails { arrayList().last() } diff --git a/libraries/stdlib/test/MapTest.kt b/libraries/stdlib/test/MapTest.kt index f7c46f6a976..6df00479012 100644 --- a/libraries/stdlib/test/MapTest.kt +++ b/libraries/stdlib/test/MapTest.kt @@ -2,18 +2,14 @@ package test.collections import kotlin.test.* -// TODO can we avoid importing all this stuff by default I wonder? -// e.g. making println and the collection builder methods public by default? -import kotlin.* -import kotlin.io.* -import kotlin.util.* import java.util.* import junit.framework.TestCase +import org.junit.Test -class MapTest() : TestCase() { - val data: java.util.Map = java.util.HashMap() +class MapTest { - fun testGetOrElse() { + Test fun getOrElse() { + val data = HashMap() val a = data.getOrElse("foo"){2} assertEquals(2, a) @@ -22,7 +18,8 @@ class MapTest() : TestCase() { assertEquals(0, data.size()) } - fun testGetOrPut() { + Test fun getOrPut() { + val data = HashMap() val a = data.getOrPut("foo"){2} assertEquals(2, a) @@ -32,17 +29,16 @@ class MapTest() : TestCase() { assertEquals(1, data.size()) } - fun testSizeAndEmpty() { + Test fun sizeAndEmpty() { + val data = HashMap() assertTrue{ data.empty } - // TODO using size breaks a test case - assertEquals(data.size(), 0) + assertEquals(data.size, 0) } - fun testSetViaIndexOperators() { - val map = java.util.HashMap() + Test fun setViaIndexOperators() { + val map = HashMap() assertTrue{ map.empty } - // TODO using size breaks a test case - assertEquals(map.size(), 0) + assertEquals(map.size, 0) map["name"] = "James"