import scala.testing.SUnit._ object Test { def main(args:Array[String]) = { Foo.run Mas.run Lis.run } } // this class is used for representation class Bar { var size: Int = 50 var name: String = "medium" } // test basic unapply for 0, 1 and 2 args and with precise type test object Fii { def unapply(x: Any): boolean = x.isInstanceOf[Bar] } object Faa { def unapply(x: Any): Option[String] = if(x.isInstanceOf[Bar]) Some(x.asInstanceOf[Bar].name) else None } object FaaPrecise { def unapply(x: Bar): Option[String] = Some(x.name) } object FaaPreciseSome { def unapply(x: Bar) = Some(x.name) // return type Some[String] } object Foo extends Assert { def unapply(x: Any): Option[Product2[Int, String]] = x match { case y: Bar => Some(Tuple(y.size, y.name)) case _ => None } def doMatch1(b:Bar) = b match { case Foo(s:Int, n:String) => {s,n} } def doMatch2(b:Bar) = b match { case Fii() => null } def doMatch3(b:Bar) = b match { case Faa(n:String) => n } def doMatch4(b:Bar) = (b:Any) match { case FaaPrecise(n:String) => n } def doMatch5(b:Bar) = (b:Any) match { case FaaPreciseSome(n:String) => n } def run { val b = new Bar assertEquals(doMatch1(b),{50,"medium"}) assertEquals(doMatch2(b),null) assertEquals(doMatch3(b),"medium") assertEquals(doMatch4(b),"medium") assertEquals(doMatch5(b),"medium") } } // same, but now object is not top-level object Mas extends Assert { object Gaz { def unapply(x: Any): Option[Product2[Int, String]] = x match { case y: Baz => Some(Tuple(y.size, y.name)) case _ => None } } class Baz { var size: Int = 60 var name: String = "too large" } def run { val b = new Baz assertEquals(b match { case Gaz(s:Int, n:String) => {s,n} }, {60,"too large"}) } } object Lis extends Assert { def run { assertEquals((List(1,2,3): Any) match { case List(x,y,_*) => {x,y}}, {1,2}) } }