//############################################################################ // Serialization //############################################################################ object Serialize { @throws(classOf[java.io.IOException]) def write[A](o: A): Array[Byte] = { val ba = new java.io.ByteArrayOutputStream(512) val out = new java.io.ObjectOutputStream(ba) out.writeObject(o) out.close() ba.toByteArray() } @throws(classOf[java.io.IOException]) @throws(classOf[ClassNotFoundException]) def read[A](buffer: Array[Byte]): A = { val in = new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer)) in.readObject().asInstanceOf[A] } def check[A, B](x: A, y: B) { println("x = " + x) println("y = " + y) println("x equals y: " + (x equals y) + ", y equals x: " + (y equals x)) assert((x equals y) && (y equals x)) println() } } import Serialize._ //############################################################################ // Test classes in package "scala" object Test1_scala { private def arrayToString[A](arr: Array[A]): String = arr.mkString("Array[",",","]") private def arrayEquals[A, B](a1: Array[A], a2: Array[B]): Boolean = (a1.length == a2.length) && (Iterator.range(0, a1.length) forall { i => a1(i) == a2(i) }) object WeekDay extends Enumeration { type WeekDay = Value val Monday, Tuesday, Wednesday, Thusday, Friday, Saturday, Sunday = Value } import WeekDay._, BigDecimal._, RoundingMode._ // in alphabetic order try { // Array val a1 = Array(1, 2, 3) val _a1: Array[Int] = read(write(a1)) println("a1 = " + arrayToString(a1)) println("_a1 = " + arrayToString(_a1)) println("arrayEquals(a1, _a1): " + arrayEquals(a1, _a1)) println() // Either val e1 = Left(1) val _e1: Either[Int, String] = read(write(e1)) println("e1 = " + e1) println("_e1 = " + _e1) println("e1 eq _e1: " + (e1 eq _e1) + ", _e1 eq e1: " + (_e1 eq e1)) println("e1 equals _e1: " + (e1 equals _e1) + ", _e1 equals e1: " + (_e1 equals e1)) println() // Enumeration val x7 = BigDecimal.RoundingMode val y7: RoundingMode.type = read(write(x7)) println("x7 = " + x7) println("y7 = " + y7) println("x7 eq y7: " + (x7 eq y7) + ", y7 eq x7: " + (y7 eq x7)) println("x7 equals y7: " + (x7 equals y7) + ", y7 equals x7: " + (y7 equals x7)) println() val x8 = WeekDay val y8: WeekDay.type = read(write(x8)) println("x8 = " + x8) println("y8 = " + y8) println("x8 eq y8: " + (x8 eq y8) + ", y8 eq x8: " + (y8 eq x8)) println("x8 equals y8: " + (x8 equals y8) + ", y8 equals x8: " + (y8 equals x8)) println() val x9 = UP val y9: RoundingMode = read(write(x9)) println("x9 = " + x9) println("y9 = " + y9) println("x9 eq y9: " + (x9 eq y9) + ", y9 eq x9: " + (y9 eq x9)) println("x9 equals y9: " + (x9 equals y9) + ", y9 equals x9: " + (y9 equals x9)) println() val x10 = Monday val y10: WeekDay = read(write(x10)) println("x10 = " + x10) println("y10 = " + y10) println("x10 eq y10: " + (x10 eq y10) + ", y10 eq x10: " + (y10 eq x10)) println("x10 equals y10: " + (x10 equals y10) + ", y10 equals x10: " + (y10 equals x10)) println() println("x9 eq x10: " + (x9 eq x10) + ", x10 eq x9: " + (x10 eq x9)) println("x9 equals x10: " + (x9 equals x10) + ", x10 equals x9: " + (x10 equals x9)) println("x9 eq y10: " + (x9 eq y10) + ", y10 eq x9: " + (y10 eq x9)) println("x9 equals y10: " + (x9 equals y10) + ", y10 equals x9: " + (y10 equals x9)) println() // Function val f1 = { x: Int => 2 * x } val _f1: Function[Int, Int] = read(write(f1)) println("f1 = ") println("_f1 = ") println("f1(2): " + f1(2) + ", _f1(2): " + _f1(2)) println() // List val xs0 = List(1, 2, 3) val _xs0: List[Int] = read(write(xs0)) println("xs0 = " + xs0) println("_xs0 = " + _xs0) println("xs0 eq _xs0: " + (xs0 eq _xs0) + ", _xs0 eq xs0: " + (_xs0 eq xs0)) println("xs0 equals _xs0: " + (xs0 equals _xs0) + ", _xs0 equals xs0: " + (_xs0 equals xs0)) println() val xs1 = Nil val _xs1: List[Nothing] = read(write(xs1)) println("xs1 = " + xs1) println("_xs1 = " + _xs1) println("xs1 eq _xs1: " + (xs1 eq _xs1) + ", _xs1 eq xs1: " + (_xs1 eq xs1)) println() // Option val o1 = None val _o1: Option[Nothing] = read(write(o1)) println("o1 = " + o1) println("_o1 = " + _o1) println("o1 eq _o1: " + (o1 eq _o1) + ", _o1 eq o1: " + (_o1 eq o1)) println() val o2 = Some(1) val _o2: Option[Int] = read(write(o2)) println("o2 = " + o2) println("_o2 = " + _o2) println("o2 eq _o2: " + (o2 eq _o2) + ", _o2 eq o2: " + (_o2 eq o2)) println("o2 equals _o2: " + (o2 equals _o2) + ", _o2 equals o2: " + (_o2 equals o2)) println() /* // Responder val r1 = Responder.constant("xyz") val _r1: Responder[String] = read(write(r1)) check(r1, _r1) */ // Symbol val s1 = 'hello val _s1: Symbol = read(write(s1)) println("s1 = " + s1) println("_s1 = " + _s1) println("s1 eq _s1: " + (s1 eq _s1) + ", _s1 eq s1: " + (_s1 eq s1)) println("s1 equals _s1: " + (s1 equals _s1) + ", _s1 equals s1: " + (_s1 equals s1)) println() // Tuple val t1 = ("BannerLimit", 12345) val _t1: (String, Int) = read(write(t1)) println("t1 = " + t1) println("_t1 = " + _t1) println("t1 eq _t1: " + (t1 eq _t1) + ", _t1 eq t1: " + (_t1 eq t1)) println("t1 equals _t1: " + (t1 equals _t1) + ", _t1 equals t1: " + (_t1 equals t1)) println() } catch { case e: Exception => println("Error in Test1_scala: " + e) throw e } } //############################################################################ // Test classes in package "scala.collection.immutable" object Test2_immutable { import scala.collection.immutable.{ BitSet, HashMap, HashSet, ListMap, ListSet, Queue, Range, SortedMap, SortedSet, Stack, Stream, TreeMap, TreeSet, Vector} // in alphabetic order try { // BitSet val bs1 = BitSet.empty + 1 + 2 val _bs1: BitSet = read(write(bs1)) check(bs1, _bs1) val bs2 = { val bs = new collection.mutable.BitSet() bs += 2; bs += 3 bs.toImmutable } val _bs2: BitSet = read(write(bs2)) check(bs2, _bs2) // HashMap val hm1 = new HashMap[Int, String] + (1 -> "A", 2 -> "B", 3 -> "C") val _hm1: HashMap[Int, String] = read(write(hm1)) check(hm1, _hm1) // HashSet val hs1 = new HashSet[Int] + 1 + 2 val _hs1: HashSet[Int] = read(write(hs1)) check(hs1, _hs1) // List val xs1 = List(("buffers", 20), ("layers", 2), ("title", 3)) val _xs1: List[(String, Int)] = read(write(xs1)) check(xs1, _xs1) // ListMap val lm1 = new ListMap[String, Int] + ("buffers" -> 20, "layers" -> 2, "title" -> 3) val _lm1: ListMap[String, Int] = read(write(lm1)) check(lm1, _lm1) // ListSet val ls1 = new ListSet[Int] + 3 + 5 val _ls1: ListSet[Int] = read(write(ls1)) check(ls1, _ls1) // Queue val q1 = Queue("a", "b", "c") val _q1: Queue[String] = read(write(q1)) check(q1, _q1) // Range val r1 = 0 until 10 val _r1: Range = read(write(r1)) check(r1, _r1) val r2 = Range.Long(0L, 10L, 1) val _r2: r2.type = read(write(r2)) check(r2, _r2) // SortedMap val sm1 = SortedMap.empty[Int, String] + (2 -> "B", 3 -> "C", 1 -> "A") val _sm1: SortedMap[Int, String] = read(write(sm1)) check(sm1, _sm1) // SortedSet val ss1 = SortedSet.empty[Int] + 2 + 3 + 1 val _ss1: SortedSet[Int] = read(write(ss1)) check(ss1, _ss1) // Stack val s1 = new Stack().push("a", "b", "c") val _s1: Stack[String] = read(write(s1)) check(s1, _s1) // Stream val st1 = Stream.range(0, 10) val _st1: Stream[Int] = read(write(st1)) check(st1, _st1) // TreeMap val tm1 = new TreeMap[Int, String] + (42 -> "FortyTwo") val _tm1: TreeMap[Int, String] = read(write(tm1)) check(tm1, _tm1) // TreeSet val ts1 = new TreeSet[Int]() + 2 + 0 val _ts1: TreeSet[Int] = read(write(ts1)) check(ts1, _ts1) // Vector val v1 = Vector('a, 'b, 'c) val _v1: Vector[Symbol] = read(write(v1)) check(v1, _v1) } catch { case e: Exception => println("Error in Test2_immutable: " + e) throw e } } //############################################################################ // Test classes in package "scala.collection.mutable" @deprecated("Suppress warnings", since="2.11") object Test3_mutable { import scala.reflect.ClassManifest import scala.collection.mutable.{ ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList, HashMap, HashSet, History, LinkedHashMap, LinkedHashSet, LinkedList, ListBuffer, Publisher, Queue, Stack, StringBuilder, WrappedArray, TreeSet} import scala.collection.concurrent.TrieMap // in alphabetic order try { // ArrayBuffer val ab1 = new ArrayBuffer[String] ab1 ++= List("one", "two") val _ab1: ArrayBuffer[String] = read(write(ab1)) check(ab1, _ab1) // ArrayBuilder val abu1 = ArrayBuilder.make[Long] val _abu1: ArrayBuilder[ClassManifest[Long]] = read(write(abu1)) check(abu1, _abu1) val abu2 = ArrayBuilder.make[Float] val _abu2: ArrayBuilder[ClassManifest[Float]] = read(write(abu2)) check(abu2, _abu2) // ArraySeq val aq1 = ArraySeq(1, 2, 3) val _aq1: ArraySeq[Int] = read(write(aq1)) check(aq1, _aq1) // ArrayStack val as1 = new ArrayStack[Int] as1 ++= List(20, 2, 3).iterator val _as1: ArrayStack[Int] = read(write(as1)) check(as1, _as1) // BitSet val bs1 = new BitSet() bs1 += 0 bs1 += 8 bs1 += 9 val _bs1: BitSet = read(write(bs1)) check(bs1, _bs1) /* // DoubleLinkedList val dl1 = new DoubleLinkedList[Int](2, null) dl1.append(new DoubleLinkedList(3, null)) val _dl1: DoubleLinkedList[Int] = read(write(dl1)) check(dl1, _dl1) */ // HashMap val hm1 = new HashMap[String, Int] hm1 ++= List(("A", 1), ("B", 2), ("C", 3)).iterator val _hm1: HashMap[String, Int] = read(write(hm1)) check(hm1, _hm1) // HashSet val hs1 = new HashSet[String] hs1 ++= List("layers", "buffers", "title").iterator val _hs1: HashSet[String] = read(write(hs1)) check(hs1, _hs1) val h1 = new History[String, Int] val _h1: History[String, Int] = read(write(h1)) check(h1, _h1) // LinkedHashMap { val lhm1 = new LinkedHashMap[String, Int] val list = List(("Linked", 1), ("Hash", 2), ("Map", 3)) lhm1 ++= list.iterator val _lhm1: LinkedHashMap[String, Int] = read(write(lhm1)) check(lhm1, _lhm1) check(lhm1.toSeq, _lhm1.toSeq) // check elements order check(lhm1.toSeq, list) // check elements order } // LinkedHashSet { val lhs1 = new LinkedHashSet[String] val list = List("layers", "buffers", "title") lhs1 ++= list.iterator val _lhs1: LinkedHashSet[String] = read(write(lhs1)) check(lhs1, _lhs1) check(lhs1.toSeq, _lhs1.toSeq) // check elements order check(lhs1.toSeq, list) // check elements order } /* // LinkedList val ll1 = new LinkedList[Int](2, null) ll1.append(new LinkedList(3, null)) val _ll1: LinkedList[Int] = read(write(ll1)) check(ll1, _ll1) */ // ListBuffer val lb1 = new ListBuffer[String] lb1 ++= List("white", "black") val _lb1: ListBuffer[String] = read(write(lb1)) check(lb1, _lb1) // Queue val q1 = new Queue[Int] q1 ++= List(20, 2, 3).iterator val _q1: Queue[Int] = read(write(q1)) check(q1, _q1) // Stack val s1 = new Stack[Int] s1 pushAll q1 val _s1: Stack[Int] = read(write(s1)) check(s1, _s1) // StringBuilder val sb1 = new StringBuilder sb1 append "abc" val _sb1: StringBuilder = read(write(sb1)) check(sb1, _sb1) // WrappedArray val wa1 = WrappedArray.make(Array(1, 2, 3)) val _wa1: WrappedArray[Int] = read(write(wa1)) check(wa1, _wa1) // TreeSet val ts1 = TreeSet[Int]() ++= Array(1, 2, 3) val _ts1: TreeSet[Int] = read(write(ts1)) check(ts1, _ts1) // concurrent.TrieMap val ct1 = TrieMap[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three") val _ct1: TrieMap[Int, String] = read(write(ct1)) check(ct1, _ct1) } catch { case e: Exception => println("Error in Test3_mutable: " + e) throw e } } //############################################################################ // Test user-defined classes WITHOUT nesting class Person(_name: String) extends Serializable { private var name = _name override def toString() = name override def equals(that: Any): Boolean = that.isInstanceOf[Person] && (name == that.asInstanceOf[Person].name) } class Employee(_name: String) extends Serializable { private var name = _name override def toString() = name } object bob extends Employee("Bob") object Test5 { val x1 = new Person("Tim") val x2 = bob try { val y1: Person = read(write(x1)) val y2: Employee = read(write(x2)) check(x1, y1) check(x2, y2) } catch { case e: Exception => println("Error in Test5: " + e) } } //############################################################################ // Test user-defined classes WITH nesting object Test6 { object bill extends Employee("Bill") { val x = paul } object paul extends Person("Paul") { val x = 4 // bill; => StackOverflowException !!! } val x1 = new Person("John") val x2 = bill val x3 = paul try { val y1: Person = read(write(x1)) val y2: Employee = read(write(x2)) val y3: Person = read(write(x3)) check(x1, y1) check(x2, y2) check(x3, y3) } catch { case e: Exception => println("Error in Test6: " + e) } } //############################################################################ // Nested objects cannot get readresolve automatically because after deserialization // they would be null (they are treated as lazy vals) class Outer extends Serializable { object Inner extends Serializable } object Test7 { val x = new Outer x.Inner // initialize val y:Outer = read(write(x)) if (y.Inner == null) println("Inner object is null") } // Verify that transient lazy vals don't get serialized class WithTransient extends Serializable { @transient lazy val a1 = 1 @transient private lazy val a2 = 2 @transient object B extends Serializable @transient private object C extends Serializable def test = { println(a1) println(a2) if (B == null || C == null) println("Transient nested object failed to serialize properly") } } object Test8 { val x = new WithTransient x.test try { val y:WithTransient = read(write(x)) y.test } catch { case e: Exception => println("Error in Test8: " + e) } } //############################################################################ // Test code @deprecated("Suppress warnings", since="2.11") object Test { def main(args: Array[String]) { Test1_scala Test2_immutable Test3_mutable Test5 Test6 Test7 Test8 Test9_parallel Test10_util } } //############################################################################ //############################################################################ // Test classes in package "scala.collection.parallel" and subpackages object Test9_parallel { import scala.collection.parallel._ try { println() // UnrolledBuffer val ub = new collection.mutable.UnrolledBuffer[String] ub ++= List("one", "two") val _ub: collection.mutable.UnrolledBuffer[String] = read(write(ub)) check(ub, _ub) // mutable.ParArray val pa = mutable.ParArray("abc", "def", "etc") val _pa: mutable.ParArray[String] = read(write(pa)) check(pa, _pa) // mutable.ParHashMap val mpm = mutable.ParHashMap(1 -> 2, 2 -> 4) val _mpm: mutable.ParHashMap[Int, Int] = read(write(mpm)) check(mpm, _mpm) // mutable.ParTrieMap val mpc = mutable.ParTrieMap(1 -> 2, 2 -> 4) val _mpc: mutable.ParTrieMap[Int, Int] = read(write(mpc)) check(mpc, _mpc) // mutable.ParHashSet val mps = mutable.ParHashSet(1, 2, 3) val _mps: mutable.ParHashSet[Int] = read(write(mps)) check(mps, _mps) // immutable.ParRange val pr1 = immutable.ParRange(0, 4, 1, true) val _pr1: immutable.ParRange = read(write(pr1)) check(pr1, _pr1) val pr2 = immutable.ParRange(0, 4, 1, false) val _pr2: immutable.ParRange = read(write(pr2)) check(pr2, _pr2) // immutable.ParHashMap val ipm = immutable.ParHashMap(5 -> 1, 10 -> 2) val _ipm: immutable.ParHashMap[Int, Int] = read(write(ipm)) check(ipm, _ipm) // immutable.ParHashSet val ips = immutable.ParHashSet("one", "two") val _ips: immutable.ParHashSet[String] = read(write(ips)) check(ips, _ips) } catch { case e: Exception => println("Error in Test5_parallel: " + e) throw e } } //############################################################################ // Test classes in package scala.util object Test10_util { import scala.util.Random def rep[A](n: Int)(f: => A) { if (n > 0) { f; rep(n-1)(f) } } { val random = new Random(345) val random2: Random = read(write(random)) rep(5) { assert(random.nextInt == random2.nextInt) } } }