From 302254f531c620688f3441bdbc1da1a4f18097fa Mon Sep 17 00:00:00 2001 From: James Strachan Date: Wed, 4 Jan 2012 11:49:34 +0000 Subject: [PATCH] enabled test case for auto-closing helper method on Closable.foreach --- stdlib/ktSrc/JavaIo.kt | 14 ++++++++++++-- testlib/test/IoTest.kt | 43 ++++++++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/stdlib/ktSrc/JavaIo.kt b/stdlib/ktSrc/JavaIo.kt index 8333eb37ca4..432e2678dad 100644 --- a/stdlib/ktSrc/JavaIo.kt +++ b/stdlib/ktSrc/JavaIo.kt @@ -67,7 +67,7 @@ private val stdin : BufferedReader = BufferedReader(InputStreamReader(object : I inline fun readLine() : String? = stdin.readLine() /** Uses the given resource then closes it to ensure its closed again */ -inline fun T.use(block: (T)-> R) : R { +inline fun T.foreach(block: (T)-> R) : R { var closed = false try { return block(this) @@ -118,7 +118,17 @@ inline fun Reader.buffered(): BufferedReader = if(this is BufferedReader) this e inline fun Reader.buffered(bufferSize: Int) = BufferedReader(this, bufferSize) -inline fun Reader.useLines(block: (Iterator) -> T): T = this.buffered().use{block(it.lineIterator())} +inline fun Reader.foreachLine(block: (String) -> Unit): Unit { + this.foreach{ + val iter = buffered().lineIterator() + while (iter.hasNext) { + val elem = iter.next() + block(elem) + } + } +} + +inline fun Reader.useLines(block: (Iterator) -> T): T = this.buffered().foreach{block(it.lineIterator())} /** * Returns an iterator over each line. * Note the caller must close the underlying BufferedReader diff --git a/testlib/test/IoTest.kt b/testlib/test/IoTest.kt index 5714c8445ff..29d3f8671a4 100644 --- a/testlib/test/IoTest.kt +++ b/testlib/test/IoTest.kt @@ -17,13 +17,14 @@ class IoTest() : TestSupport() { reader.close() } } - + fun sample() : Reader { - return StringReader("""Hello -World"""); + return StringReader("Hello\nWorld"); } fun testLineIterator() { + // TODO we should maybe zap the useLines approach as it encourages + // use of iterators which don't close the underlying stream val list1 = sample().useLines{it.toArrayList()} val list2 = sample().useLines>{it.toArrayList()} @@ -31,20 +32,42 @@ World"""); assertEquals(arrayList("Hello", "World"), list2) } - fun testUse() { - /** + fun testForEach() { val list = ArrayList() val reader = sample().buffered() - TODO compiler error? - reader.use{ - val line = it.readLine() - if (line != null) { - list.add(line) + reader.foreach{ + while (true) { + val line = it.readLine() + if (line != null) + list.add(line) + else + break } } assertEquals(arrayList("Hello", "World"), list) + } + + fun testForEachLine() { + val list = ArrayList() + val reader = sample() + + /* TODO would be nicer maybe to write this as + reader.lines.foreach { ... } + + as we could one day maybe one day write that as + for (line in reader.lines) + + if the for(elem in thing) {...} statement could act as syntax sugar for + thing.foreach{ elem -> ... } + + if thing is not an Iterable/array/Iterator but has a suitable foreach method */ + reader.foreachLine{ + list.add(it) + } + + assertEquals(arrayList("Hello", "World"), list) } }