summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2014-09-05 00:24:27 -0700
committerSom Snytt <som.snytt@gmail.com>2014-11-11 07:33:52 -0800
commitda60dda202f386ed85fa15bf8fe02252d4dfb911 (patch)
treee452ff2e24d9ac3ff0c5441b269e974323e88644
parentd28d4f49088eb5e0809cbb68655319c68e981caa (diff)
downloadscala-da60dda202f386ed85fa15bf8fe02252d4dfb911.tar.gz
scala-da60dda202f386ed85fa15bf8fe02252d4dfb911.tar.bz2
scala-da60dda202f386ed85fa15bf8fe02252d4dfb911.zip
SI-8835 Iterator tests can be junit
Without loss of generality or convenience, but helps reduce the number of files in test/files and may reduce compile times for test suite. This commit includes the fix from #3963 and an extra test of that fix that ensures the stack doesn't grow on chained drops.
-rw-r--r--src/library/scala/collection/Iterator.scala4
-rw-r--r--test/files/run/iterator-concat.check4
-rw-r--r--test/files/run/iterator-concat.scala15
-rw-r--r--test/files/run/iterator-iterate-lazy.scala5
-rw-r--r--test/files/run/iterators.check14
-rw-r--r--test/files/run/iterators.scala168
-rw-r--r--test/files/run/t3516.check3
-rw-r--r--test/files/run/t3516.scala13
-rw-r--r--test/junit/scala/collection/IteratorTest.scala148
-rw-r--r--test/junit/scala/tools/testing/AssertUtil.scala20
10 files changed, 167 insertions, 227 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 0115cc154c..20712f918c 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -322,8 +322,8 @@ trait Iterator[+A] extends TraversableOnce[A] {
*/
def drop(n: Int): Iterator[A] = {
var j = 0
- while (j < n && this.hasNext) {
- this.next
+ while (j < n && hasNext) {
+ next()
j += 1
}
this
diff --git a/test/files/run/iterator-concat.check b/test/files/run/iterator-concat.check
deleted file mode 100644
index 23835b07ae..0000000000
--- a/test/files/run/iterator-concat.check
+++ /dev/null
@@ -1,4 +0,0 @@
-100
-1000
-10000
-100000
diff --git a/test/files/run/iterator-concat.scala b/test/files/run/iterator-concat.scala
deleted file mode 100644
index f11363410f..0000000000
--- a/test/files/run/iterator-concat.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-object Test {
- // Create `size` Function0s, each of which evaluates to an Iterator
- // which produces 1. Then fold them over ++ to get a single iterator,
- // which should sum to "size".
- def mk(size: Int): Iterator[Int] = {
- val closures = (1 to size).toList.map(x => (() => Iterator(1)))
- closures.foldLeft(Iterator.empty: Iterator[Int])((res, f) => res ++ f())
- }
- def main(args: Array[String]): Unit = {
- println(mk(100).sum)
- println(mk(1000).sum)
- println(mk(10000).sum)
- println(mk(100000).sum)
- }
-}
diff --git a/test/files/run/iterator-iterate-lazy.scala b/test/files/run/iterator-iterate-lazy.scala
deleted file mode 100644
index 92b170062e..0000000000
--- a/test/files/run/iterator-iterate-lazy.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-object Test {
- def main(args: Array[String]): Unit = {
- Iterator.iterate((1 to 5).toList)(_.tail).takeWhile(_.nonEmpty).map(_.head).toList
- }
-}
diff --git a/test/files/run/iterators.check b/test/files/run/iterators.check
deleted file mode 100644
index abaf80ff38..0000000000
--- a/test/files/run/iterators.check
+++ /dev/null
@@ -1,14 +0,0 @@
-test check_from was successful
-test check_range was successful
-test check_range2 was successful
-test check_range3 was successful
-test check_take was successful
-test check_drop was successful
-test check_slice was successful
-test check_foreach was successful
-test check_forall was successful
-test check_fromArray was successful
-test check_toSeq was successful
-test check_indexOf was successful
-test check_findIndexOf was successful
-
diff --git a/test/files/run/iterators.scala b/test/files/run/iterators.scala
deleted file mode 100644
index d54da3d3ba..0000000000
--- a/test/files/run/iterators.scala
+++ /dev/null
@@ -1,168 +0,0 @@
-//############################################################################
-// Iterators
-//############################################################################
-
-//############################################################################
-
-import scala.language.postfixOps
-
-object Test {
-
- def check_from: Int = {
- val it1 = Iterator.from(-1)
- val it2 = Iterator.from(0, -1)
- it1.next + it2.next
- }
-
- def check_range: Int = {
- val xs1 = Iterator.range(0, 10, 2) toList;
- val xs2 = Iterator.range(0, 10, -2) toList;
- val xs3 = Iterator.range(10, 0, -2) toList;
- val xs4 = Iterator.range(10, 0, 2) toList;
- val xs5 = Iterator.range(0, 10, 11) toList;
- xs1.length + xs2.length + xs3.length + xs4.length + xs5.length
- }
-
- def check_range2: Int = {
- val r1start = 0
- val r1end = 10
- val r1step = 1
- val r1 = Iterator.range(r1start, r1end, r1step) toList;
- val r2 = Iterator.range(r1start, r1end, r1step + 1) toList;
- val r3 = Iterator.range(r1end, r1start, -r1step) toList;
- val r4 = Iterator.range(0, 10, 11) toList;
- // 10 + 5 + 10 + 1
- r1.length + r2.length + r3.length + r4.length
- }
-
- def check_range3: Int = {
- def trues(xs: List[Boolean]) = xs.foldLeft(0)((a, b) => if (b) a+1 else a)
- val r1 = Iterator.range(0, 10)
- val xs1 = List(r1 contains 5, r1 contains 6)
- val r2a = Iterator.range(0, 10, 2)
- val r2b = Iterator.range(0, 10, 2)
- val xs2 = List(r2a contains 5, r2b contains 6)
- val r3 = Iterator.range(0, 10, 11)
- val xs3 = List(r3 contains 5, r3 contains 6)
- // 2 + 1 + 0
- trues(xs1) + trues(xs2) + trues(xs3)
- }
-
- def check_take: Int = {
- val it1 = Iterator.from(0)
- val xs1 = it1 take 10 toList;
- xs1.length
- }
-
- def check_drop: Int = {
- val tests = Array(
- Iterator.from(0).take(5).drop(1).toSeq sameElements Seq(1, 2, 3, 4),
- Iterator.from(0).take(5).drop(3).toSeq sameElements Seq(3, 4),
-
- Iterator.from(0).take(5).drop(5).toSeq sameElements Seq(),
- Iterator.from(0).take(5).drop(10).toSeq sameElements Seq(),
-
- Iterator.from(0).take(5).drop(0).toSeq sameElements Seq(0, 1, 2, 3, 4),
- Iterator.from(0).take(5).drop(-1).toSeq sameElements Seq(0, 1, 2, 3, 4),
-
- Iterator.from(0).take(5).drop(1).map(2 * _).toSeq sameElements Seq(2, 4, 6, 8),
- Iterator.from(0).take(5).map(2 * _).drop(1).toSeq sameElements Seq(2, 4, 6, 8),
-
- Iterator.from(0).take(5).drop(1).drop(2).toSeq sameElements Seq(3, 4),
- Iterator.from(0).take(5).drop(2).drop(1).toSeq sameElements Seq(3, 4)
- )
- tests.count(result => result)
- }
-
- def check_slice: Int = {
- val tests = Array(
- Iterator.from(0).slice(3, 7).toSeq sameElements Seq(3, 4, 5, 6),
- Iterator.from(0).slice(3, 3).toSeq sameElements Seq(),
- Iterator.from(0).slice(-1, 3).toSeq sameElements Seq(0, 1, 2),
- Iterator.from(0).slice(3, -1).toSeq sameElements Seq(),
-
- Iterator.from(0).slice(3, 7).map(2 * _).toSeq sameElements Seq(6, 8, 10, 12),
- Iterator.from(0).map(2 * _).slice(3, 7).toSeq sameElements Seq(6, 8, 10, 12),
-
- Iterator.from(0).slice(3, 7).drop(1).toSeq sameElements Seq(4, 5, 6),
- Iterator.from(0).drop(1).slice(3, 7).toSeq sameElements Seq(4, 5, 6, 7),
-
- Iterator.from(0).slice(3, 7).slice(1, 3).toSeq sameElements Seq(4, 5),
- Iterator.from(0).slice(3, 7).slice(1, 10).toSeq sameElements Seq(4, 5, 6)
- )
- tests.count(result => result)
- }
-
- def check_foreach: Int = {
- val it1 = Iterator.from(0) take 20
- var n = 0
- it1 foreach { n += _ }
- n
- }
-
- def check_forall: Int = {
- val it1 = Iterator.from(0)
- val it2 = Iterator.from(1)
- 0
- }
-
- def check_fromArray: Int = { // ticket #429
- val a = List(1, 2, 3, 4).toArray
- var xs0 = a.iterator.toList;
- var xs1 = a.slice(0, 1).iterator.toList;
- var xs2 = a.slice(0, 2).iterator.toList;
- var xs3 = a.slice(0, 3).iterator.toList;
- var xs4 = a.slice(0, 4).iterator.toList;
- xs0.length + xs1.length + xs2.length + xs3.length + xs4.length
- }
-
- def check_toSeq: String =
- List(1, 2, 3, 4, 5).iterator.toSeq.mkString("x")
-
- def check_indexOf: String = {
- val i = List(1, 2, 3, 4, 5).indexOf(4)
- val j = List(1, 2, 3, 4, 5).indexOf(16)
- "" + i + "x" + j
- }
-
- def check_findIndexOf: String = {
- val i = List(1, 2, 3, 4, 5).indexWhere { x: Int => x >= 4 }
- val j = List(1, 2, 3, 4, 5).indexWhere { x: Int => x >= 16 }
- "" + i + "x" + j
- }
-
- def check_success[A](name: String, closure: => A, expected: A) {
- print("test " + name)
- try {
- val actual: A = closure
- if (actual == expected)
- print(" was successful")
- else
- print(" failed: expected "+ expected +", found "+ actual)
- }
- catch {
- case exception: Throwable =>
- print(" raised exception " + exception)
- }
- println()
- }
-
- def main(args: Array[String]) {
- check_success("check_from", check_from, -1)
- check_success("check_range", check_range, 11)
- check_success("check_range2", check_range2, 26)
- check_success("check_range3", check_range3, 3)
- check_success("check_take", check_take, 10)
- check_success("check_drop", check_drop, 10)
- check_success("check_slice", check_slice, 10)
- check_success("check_foreach", check_foreach, 190)
- check_success("check_forall", check_forall, 0)
- check_success("check_fromArray",check_fromArray, 14)
- check_success("check_toSeq", check_toSeq, "1x2x3x4x5")
- check_success("check_indexOf", check_indexOf, "3x-1")
- check_success("check_findIndexOf", check_findIndexOf, "3x-1")
- println()
- }
-}
-
-//############################################################################
diff --git a/test/files/run/t3516.check b/test/files/run/t3516.check
deleted file mode 100644
index d0d10d82fa..0000000000
--- a/test/files/run/t3516.check
+++ /dev/null
@@ -1,3 +0,0 @@
-1
-1
-21
diff --git a/test/files/run/t3516.scala b/test/files/run/t3516.scala
deleted file mode 100644
index aa302ce85a..0000000000
--- a/test/files/run/t3516.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-object Test {
- def mkIterator = (1 to 5).iterator map (x => { println(x) ; x })
- def mkInfinite = Iterator continually { println(1) ; 1 }
-
- def main(args: Array[String]): Unit = {
- // Stream is strict in its head so we should see 1 from each of them.
- val s1 = mkIterator.toStream
- val s2 = mkInfinite.toStream
- // back and forth without slipping into nontermination.
- println((Stream from 1).toIterator.drop(10).toStream.drop(10).toIterator.next)
- ()
- }
-}
diff --git a/test/junit/scala/collection/IteratorTest.scala b/test/junit/scala/collection/IteratorTest.scala
index b7a9805c9f..04af074ac7 100644
--- a/test/junit/scala/collection/IteratorTest.scala
+++ b/test/junit/scala/collection/IteratorTest.scala
@@ -6,11 +6,12 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import scala.tools.testing.AssertUtil._
+
@RunWith(classOf[JUnit4])
class IteratorTest {
- @Test
- def groupedIteratorShouldNotAskForUnneededElement(): Unit = {
+ @Test def groupedIteratorShouldNotAskForUnneededElement(): Unit = {
var counter = 0
val it = new Iterator[Int] { var i = 0 ; def hasNext = { counter = i; true } ; def next = { i += 1; i } }
val slidingIt = it sliding 2
@@ -25,4 +26,147 @@ class IteratorTest {
slidingIt.next
assertEquals("Counter should be one, that means we didn't look further than needed", 1, counter)
}
+
+ @Test def dropDoesNotGrowStack(): Unit = {
+ def it = new Iterator[Throwable] { def hasNext = true ; def next = new Throwable }
+
+ assertEquals(it.drop(1).next.getStackTrace.length, it.drop(1).drop(1).next.getStackTrace.length)
+ }
+
+ @Test def dropIsChainable(): Unit = {
+ assertSameElements(1 to 4, Iterator.from(0).take(5).drop(1).toList)
+ assertSameElements(3 to 4, Iterator.from(0).take(5).drop(3).toList)
+ assertSameElements(Seq.empty, Iterator.from(0).take(5).drop(5).toList)
+ assertSameElements(Seq.empty, Iterator.from(0).take(5).drop(10).toList)
+ assertSameElements(0 to 4, Iterator.from(0).take(5).drop(0).toList)
+ assertSameElements(0 to 4, Iterator.from(0).take(5).drop(-1).toList)
+ assertSameElements(2 to 8 by 2, (Iterator from 0 take 5 drop 1 map (2 * _)).toList)
+ assertSameElements(2 to 8 by 2, (Iterator from 0 take 5 map (2 * _) drop 1).toList)
+ assertSameElements(3 to 4, (Iterator from 0 take 5 drop 1 drop 2).toList)
+ assertSameElements(3 to 4, (Iterator from 0 take 5 drop 2 drop 1).toList)
+ }
+
+ @Test def sliceIsChainable(): Unit = {
+ assertSameElements(3 to 6, Iterator from 0 slice (3, 7))
+ assertSameElements(Seq.empty, Iterator from 0 slice (3, 3))
+ assertSameElements(0 to 2, Iterator from 0 slice (-1, 3))
+ assertSameElements(Seq.empty, Iterator from 0 slice (3, -1))
+ assertSameElements(6 to 12 by 2, Iterator from 0 slice (3, 7) map (2 * _))
+ assertSameElements(6 to 12 by 2, Iterator from 0 map (2 * _) slice (3, 7))
+ assertSameElements(4 to 6, Iterator from 0 slice (3, 7) drop 1)
+ assertSameElements(4 to 7, Iterator from 0 drop 1 slice (3, 7))
+ assertSameElements(4 to 5, Iterator from 0 slice (3, 7) slice (1, 3))
+ assertSameElements(4 to 6, Iterator from 0 slice (3, 7) slice (1, 10))
+ }
+
+ // test/files/run/iterator-concat.scala
+ @Test def concatIsStackFriendly(): Unit = {
+ // Create `size` Function0s, each of which evaluates to an Iterator
+ // which produces 1. Then fold them over ++ to get a single iterator,
+ // which should sum to "size".
+ def mk(size: Int): Iterator[Int] = {
+ //val closures = (1 to size).toList.map(x => (() => Iterator(1)))
+ //closures.foldLeft(Iterator.empty: Iterator[Int])((res, f) => res ++ f())
+ List.fill(size)(() => Iterator(1)).foldLeft(Iterator.empty: Iterator[Int])((res, f) => res ++ f())
+ }
+ assertEquals(100, mk(100).sum)
+ assertEquals(1000, mk(1000).sum)
+ assertEquals(10000, mk(10000).sum)
+ assertEquals(100000, mk(100000).sum)
+ }
+
+ @Test def from(): Unit = {
+ val it1 = Iterator.from(-1)
+ val it2 = Iterator.from(0, -1)
+ assertEquals(-1, it1.next() + it2.next())
+ }
+ @Test def range(): Unit = {
+ val xs1 = Iterator.range(0, 10, 2)
+ val xs2 = Iterator.range(0, 10, -2)
+ val xs3 = Iterator.range(10, 0, -2)
+ val xs4 = Iterator.range(10, 0, 2)
+ val xs5 = Iterator.range(0, 10, 11)
+ assertEquals(11, xs1.size + xs2.size + xs3.size + xs4.size + xs5.size)
+ }
+ @Test def range2(): Unit = {
+ val r1start = 0
+ val r1end = 10
+ val r1step = 1
+ val r1 = Iterator.range(r1start, r1end, r1step)
+ val r2 = Iterator.range(r1start, r1end, r1step + 1)
+ val r3 = Iterator.range(r1end, r1start, -r1step)
+ val r4 = Iterator.range(0, 10, 11)
+ // 10 + 5 + 10 + 1
+ assertEquals(10 + 5 + 10 + 1, r1.size + r2.size + r3.size + r4.size)
+ }
+ @Test def range3(): Unit = {
+ def trues(xs: List[Boolean]) = xs.foldLeft(0)((a, b) => if (b) a+1 else a)
+ val r1 = Iterator.range(0, 10)
+ val xs1 = List(r1 contains 5, r1 contains 6)
+ val r2a = Iterator.range(0, 10, 2)
+ val r2b = Iterator.range(0, 10, 2)
+ val xs2 = List(r2a contains 5, r2b contains 6)
+ val r3 = Iterator.range(0, 10, 11)
+ val xs3 = List(r3 contains 5, r3 contains 6)
+ // 2 + 1 + 0
+ assertEquals(2 + 1 + 0, trues(xs1) + trues(xs2) + trues(xs3))
+ }
+ @Test def take(): Unit = {
+ val it1 = Iterator.from(0)
+ val xs1 = it1 take 10
+ assertEquals(10, xs1.size)
+ }
+ @Test def foreach(): Unit = {
+ val it1 = Iterator.from(0) take 20
+ var n = 0
+ it1 foreach { n += _ }
+ assertEquals(190, n)
+ }
+ /* ???
+ @Test def forall(): Unit = {
+ val it1 = Iterator.from(0)
+ val it2 = Iterator.from(1)
+ 0
+ }
+ */
+ // ticket #429
+ @Test def fromArray(): Unit = {
+ val a = List(1, 2, 3, 4).toArray
+ var xs0 = a.iterator.toList;
+ var xs1 = a.slice(0, 1).iterator
+ var xs2 = a.slice(0, 2).iterator
+ var xs3 = a.slice(0, 3).iterator
+ var xs4 = a.slice(0, 4).iterator
+ assertEquals(14, xs0.size + xs1.size + xs2.size + xs3.size + xs4.size)
+ }
+ @Test def toSeq(): Unit = {
+ assertEquals("1x2x3x4x5", List(1, 2, 3, 4, 5).iterator.mkString("x"))
+ }
+ @Test def indexOf(): Unit = {
+ assertEquals(3, List(1, 2, 3, 4, 5).indexOf(4))
+ assertEquals(-1, List(1, 2, 3, 4, 5).indexOf(16))
+ }
+ @Test def indexWhere(): Unit = {
+ assertEquals(3, List(1, 2, 3, 4, 5).indexWhere { x: Int => x >= 4 })
+ assertEquals(-1, List(1, 2, 3, 4, 5).indexWhere { x: Int => x >= 16 })
+ }
+ // iterator-iterate-lazy.scala
+ // was java.lang.UnsupportedOperationException: tail of empty list
+ @Test def iterateIsSufficientlyLazy(): Unit = {
+ //Iterator.iterate((1 to 5).toList)(_.tail).takeWhile(_.nonEmpty).toList // suffices
+ Iterator.iterate((1 to 5).toList)(_.tail).takeWhile(_.nonEmpty).map(_.head).toList
+ }
+ // SI-3516
+ @Test def toStreamIsSufficientlyLazy(): Unit = {
+ val results = collection.mutable.ListBuffer.empty[Int]
+ def mkIterator = (1 to 5).iterator map (x => { results += x ; x })
+ def mkInfinite = Iterator continually { results += 1 ; 1 }
+
+ // Stream is strict in its head so we should see 1 from each of them.
+ val s1 = mkIterator.toStream
+ val s2 = mkInfinite.toStream
+ // back and forth without slipping into nontermination.
+ results += (Stream from 1).toIterator.drop(10).toStream.drop(10).toIterator.next()
+ assertSameElements(List(1,1,21), results)
+ }
}
diff --git a/test/junit/scala/tools/testing/AssertUtil.scala b/test/junit/scala/tools/testing/AssertUtil.scala
index 9b4833d46b..83a637783f 100644
--- a/test/junit/scala/tools/testing/AssertUtil.scala
+++ b/test/junit/scala/tools/testing/AssertUtil.scala
@@ -1,6 +1,11 @@
package scala.tools
package testing
+import org.junit.Assert
+import Assert.fail
+import scala.runtime.ScalaRunTime.stringOf
+import scala.collection.{ GenIterable, IterableLike }
+
/** This module contains additional higher-level assert statements
* that are ultimately based on junit.Assert primitives.
*/
@@ -21,6 +26,19 @@ object AssertUtil {
throw e
else return
}
- throw new AssertionError("Expression did not throw!")
+ fail("Expression did not throw!")
}
+
+ /** JUnit-style assertion for `IterableLike.sameElements`.
+ */
+ def assertSameElements[A, B >: A](expected: IterableLike[A, _], actual: GenIterable[B], message: String = ""): Unit =
+ if (!(expected sameElements actual))
+ fail(
+ f"${ if (message.nonEmpty) s"$message " else "" }expected:<${ stringOf(expected) }> but was:<${ stringOf(actual) }>"
+ )
+
+ /** Convenient for testing iterators.
+ */
+ def assertSameElements[A, B >: A](expected: IterableLike[A, _], actual: Iterator[B]): Unit =
+ assertSameElements(expected, actual.toList, "")
}