From d1dbf1864c4853854701c1b0c51c0e5e21eda9d8 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Fri, 10 Feb 2017 08:22:14 +1000 Subject: SI-10177 Override lazy operations to preserve TrieMap's semantics Calling .iterator on a TrieMap gives a read-only snapshot. This then extends to most inherited implementations written in terms of .iterator. However, some inherited methods, such as .values, either defer the call to .iterator or call it more than once. This results in subsequent mutations to the original map being visible I reviewed the inherited implementations from MapLike and found we needed overrides of `values`, `keySet`, `filterKeys`, and `mapValues`. Like `iterator`, these now create a read-only snapshot. --- .../scala/collection/concurrent/TrieMapTest.scala | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 test/junit/scala/collection/concurrent/TrieMapTest.scala (limited to 'test') diff --git a/test/junit/scala/collection/concurrent/TrieMapTest.scala b/test/junit/scala/collection/concurrent/TrieMapTest.scala new file mode 100644 index 0000000000..ed67f3e9a9 --- /dev/null +++ b/test/junit/scala/collection/concurrent/TrieMapTest.scala @@ -0,0 +1,54 @@ +package scala.collection.concurrent + +import org.junit.{Assert, Test} + +class TrieMapTest { + + private def check[T](result2: List[Any])(f: TrieMap[String, String] => TraversableOnce[Any]) = { + val m = TrieMap[String, String]() + val values = f(m) + m.put("k", "v") + Assert.assertEquals(Nil, values.toList) + Assert.assertEquals(result2, f(m).toList) + } + + @Test + def iterator(): Unit = { + check(List(("k", "v")))(_.iterator) + } + + @Test + def values(): Unit = { + check(List("v"))(_.values) + } + + @Test + def valuesIterator(): Unit = { + check(List("v"))(_.valuesIterator) + } + + @Test + def keySet(): Unit = { + check(List("k"))(_.keySet) + } + + @Test + def keysIterator(): Unit = { + check(List("k"))(_.keysIterator) + } + + @Test + def keys(): Unit = { + check(List("k"))(_.keys) + } + + @Test + def filterKeys(): Unit = { + check(List(("k", "v")))(_.filterKeys(_ => true)) + } + + @Test + def mapValues(): Unit = { + check(List(("k", "v")))(_.mapValues(x => x)) + } +} -- cgit v1.2.3