From d38fab4e8604dbaced06dbfde9d2ae1c8ba2e1de Mon Sep 17 00:00:00 2001 From: Tomasz Bartczak Date: Sun, 23 Feb 2014 20:18:42 +0100 Subject: [PATCH 01/81] made test data to test that result sequence is sorted by person name --- .../org/scalalabs/basic/lab02/CollectionExerciseTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/labs/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala b/labs/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala index 35864f47..fd7b01ff 100644 --- a/labs/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala +++ b/labs/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala @@ -37,7 +37,7 @@ class CollectionExerciseTest extends Specification { val erik = new Person(24, "Erik") val susy = new Person(40, "Susy") - val result = CollectionExercise02.groupAdultsPerAgeGroup(Seq(jack, duke, jeniffer, erik, susy)) + val result = CollectionExercise02.groupAdultsPerAgeGroup(Seq(jack, jeniffer, duke, erik, susy)) Map(20 -> Seq(erik), 30 -> Seq(duke, jeniffer), 40 -> Seq(susy)) ==== result } } From d36b2e575c304307c470945a4ba889b287982bbe Mon Sep 17 00:00:00 2001 From: Tomasz Bartczak Date: Sun, 23 Feb 2014 20:19:07 +0100 Subject: [PATCH 02/81] case class introduced for better readability of failed test --- .../scala/org/scalalabs/basic/lab02/CollectionExercise.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala b/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala index b58da89a..b21ea1b3 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala @@ -40,7 +40,7 @@ object CollectionExercise01 { object CollectionExercise02 { - class Person(val age: Int, val name: String) + case class Person(val age: Int, val name: String) /** * Take a look at the java class: {@link ImperativeSample}. The From 98d2a4a11066d6f444b305e8ea3d2ff0eb33818b Mon Sep 17 00:00:00 2001 From: upeter Date: Wed, 16 Apr 2014 16:02:24 +0200 Subject: [PATCH 03/81] type class exercises --- .../lab04/ImplictConversionExercise02.scala | 29 ++++++++++++++- .../lab04/ImplictConversionExercise02.scala | 35 +++++++++++++++++++ .../ImplictConversionExercise02Test.scala | 15 +++++++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala index 0b188a0d..dadf5de9 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala @@ -4,6 +4,7 @@ import org.joda.time.{ Duration, DateTime } import scala.math._ import language.implicitConversions import language.higherKinds +import scala.util.parsing.json.JSONObject case class Euro(val euros: Int, val cents: Int) @@ -12,7 +13,14 @@ object Euro { } /** - * Exercise 2: + * Only used for exercise2! + */ +trait JsonConverter[T] { + def toJSON(t: T): JSONObject + def fromJson(json: JSONObject): T +} +/** + * Exercise 1: * Create a money DSL which allows you to create Euro classes as follows: * - 2 euros => Euro(2, 0) * - 40 cents => Euro(0, 40) @@ -27,5 +35,24 @@ object Euro { object Exercise01 { } +/** + * Exercise 2: + * Implement a type class pattern to convert domain objects to and from json. + * Take a look at the already defined type class trait @see JsonConverter. + * 1. Implement the methods of the JsonCoverter object below that converts domain objects to and from json making use of the JsonConverter type class trait. + * 2. Provide an implementation of the JsonConverter type class trait for the Euro class. + * Place the implementation in the Euro's companion object so that the implicit resolution requires no import. + */ +object Exercise02 { + object JsonConverter { + def convertToJson[T/**provide context bound*/](t: T): JSONObject = { + ??? + } + def parseFromJson[T/**provide context bound*/](json: JSONObject): T = { + ??? + } + } + +} diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala index c34a7c9a..7f47293a 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala @@ -8,10 +8,30 @@ import scala.util.parsing.json.JSONObject import scala.util.control._ object ImplicitConversionExercises02 { + case class Euro(val euros: Int, val cents: Int) object Euro { def fromCents(cents: Int) = new Euro(cents / 100, cents % 100) + + implicit object EuroAsJsonConverter extends JsonConverter[Euro] { + override def toJSON(e: Euro): JSONObject = JSONObject(Map("symbol" -> "EUR", "amount" -> s"${e.euros},${e.cents}")) + override def fromJson(json: JSONObject): Euro = { + val opt = for { + eurosOpt <- json.obj.get("amount") + amount = eurosOpt.toString.split(",") + (euros, cents) <- Exception.allCatch.opt(amount(0).toInt -> amount(1).toInt) + } yield Euro(euros, cents) + opt.getOrElse(Euro(0, 0)) + } + } + } + + import annotation.implicitNotFound + @implicitNotFound(msg = "Cannot find JsonParser type class for ${T}") + trait JsonConverter[T] { + def toJSON(t: T): JSONObject + def fromJson(json: JSONObject): T } /** @@ -29,4 +49,19 @@ object ImplicitConversionExercises02 { implicit def fromInt(value: Int): EuroBuilder = new EuroBuilder(value, 0) } + /** + * ======================================================= + */ + object Exercise02 { + + object JsonConverter { + def convertToJson[T: JsonConverter](t: T): JSONObject = { + implicitly[JsonConverter[T]].toJSON(t) + } + def parseFromJson[T: JsonConverter](json: JSONObject): T = { + implicitly[JsonConverter[T]].fromJson(json) + } + } + + } } diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala index b479a4c7..6aae9999 100644 --- a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala +++ b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala @@ -1,6 +1,7 @@ package org.scalalabs.basic.lab04 import ImplicitConversionExercises02._ import ImplicitConversionExercises02.Exercise01._ +import ImplicitConversionExercises02.Exercise02._ import org.joda.time.Duration import org.junit.runner.RunWith import org.specs2.mutable.Specification @@ -22,5 +23,17 @@ class ImplictConversionExercise02Test extends Specification with DeactivatedTime Euro(2, 25) must be_==~(2 euros 25 cents) } } - + "Exercise02" should { + import JsonConverter._ + val euro = Euro(1, 2) + val json = JSONObject(Map("symbol" -> "EUR", "amount" -> s"${euro.euros},${euro.cents}")) + "convert Euro to json" in { + val out = convertToJson(euro) + out ==== json + } + "convert json to Euro" in { + val in = parseFromJson[Euro](json) + euro === in + } + } } \ No newline at end of file From ff619f7d6136a817145abd819a00ef12b271c6fa Mon Sep 17 00:00:00 2001 From: upeter Date: Wed, 16 Apr 2014 16:05:53 +0200 Subject: [PATCH 04/81] fixed commented code --- .../src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala | 3 --- 1 file changed, 3 deletions(-) diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala b/solutions/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala index 4d06b98b..294c3ad9 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala @@ -1,7 +1,6 @@ package org.scalalabs.basic.lab01 import scala.language.implicitConversions -import org.scalalabs.basic.lab01.DefaultCurrencyConverter abstract class Currency(val symbol: String) class Euro(val euro: Int, val cents: Int = 0) extends Currency("EUR") with Ordered[Euro] { @@ -27,8 +26,6 @@ object Euro { //implicit def fromDollar(dollar: Dollar): Euro = Euro.fromCents((DefaultCurrencyConverter.toEuroCents(dollar.inCents)).toInt) implicit def fromDollar(dollar: Dollar)(implicit converter:CurrencyConverter): Euro = Euro.fromCents(converter.toEuroCents(dollar.inCents)) - - } class Dollar(val dollar: Int, val cents: Int = 0) extends Currency("USD") { From 20996ac2d3151ed9991c9eb88e05c30228f0fe1c Mon Sep 17 00:00:00 2001 From: upeter Date: Wed, 16 Apr 2014 16:33:55 +0200 Subject: [PATCH 05/81] typo in implicit exercise --- ...ala => ImplicitConversionExercise01.scala} | 2 +- ...ala => ImplicitConversionExercise02.scala} | 0 ...=> ImplicitConversionExercise01Test.scala} | 14 +++---- .../ImplicitConversionExercise02Test.scala | 39 +++++++++++++++++++ .../ImplictConversionExercise02Test.scala | 23 ----------- ...ala => ImplicitConversionExercise01.scala} | 2 +- ...ala => ImplicitConversionExercise02.scala} | 0 ...=> ImplicitConversionExercise01Test.scala} | 12 +++--- ...=> ImplicitConversionExercise02Test.scala} | 0 9 files changed, 54 insertions(+), 38 deletions(-) rename labs/src/main/scala/org/scalalabs/basic/lab04/{ImplictConversionExercise01.scala => ImplicitConversionExercise01.scala} (98%) rename labs/src/main/scala/org/scalalabs/basic/lab04/{ImplictConversionExercise02.scala => ImplicitConversionExercise02.scala} (100%) rename labs/src/test/scala/org/scalalabs/basic/lab04/{ImplictConversionExercise01Test.scala => ImplicitConversionExercise01Test.scala} (80%) create mode 100644 labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala delete mode 100644 labs/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala rename solutions/src/main/scala/org/scalalabs/basic/lab04/{ImplictConversionExercise01.scala => ImplicitConversionExercise01.scala} (99%) rename solutions/src/main/scala/org/scalalabs/basic/lab04/{ImplictConversionExercise02.scala => ImplicitConversionExercise02.scala} (100%) rename solutions/src/test/scala/org/scalalabs/basic/lab04/{ImplictConversionExercise01Test.scala => ImplicitConversionExercise01Test.scala} (81%) rename solutions/src/test/scala/org/scalalabs/basic/lab04/{ImplictConversionExercise02Test.scala => ImplicitConversionExercise02Test.scala} (100%) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01.scala b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01.scala similarity index 98% rename from labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01.scala rename to labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01.scala index 3e6e2140..bafb2aed 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01.scala @@ -23,7 +23,7 @@ import language.higherKinds * */ -object ImplictConversionExercise01 { +object ImplicitConversionExercise01 { object Exercise01 { diff --git a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala similarity index 100% rename from labs/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala rename to labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala diff --git a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01Test.scala b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01Test.scala similarity index 80% rename from labs/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01Test.scala rename to labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01Test.scala index 6ffdc00a..2a1f08d5 100644 --- a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01Test.scala +++ b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01Test.scala @@ -1,9 +1,9 @@ package org.scalalabs.basic.lab04 -import ImplictConversionExercise01._ -import ImplictConversionExercise01.Exercise01._ -import ImplictConversionExercise01.Exercise02._ -import ImplictConversionExercise01.Exercise03._ -import ImplictConversionExercise01.Exercise04._ +import ImplicitConversionExercise01._ +import ImplicitConversionExercise01.Exercise01._ +import ImplicitConversionExercise01.Exercise02._ +import ImplicitConversionExercise01.Exercise03._ +import ImplicitConversionExercise01.Exercise04._ import org.joda.time.Duration import org.junit.runner.RunWith @@ -11,10 +11,10 @@ import org.specs2.mutable.Specification import org.specs2.runner.JUnitRunner import org.joda.time._ /** - * @see ImplictConversionExercise01 + * @see ImplicitConversionExercise01 */ @RunWith(classOf[JUnitRunner]) -class ImplictConversionExercise01Test extends Specification with DeactivatedTimeConversions { +class ImplicitConversionExercise01Test extends Specification with DeactivatedTimeConversions { "Exercise01" should { "convert string to list" in { diff --git a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala new file mode 100644 index 00000000..556e1447 --- /dev/null +++ b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala @@ -0,0 +1,39 @@ +package org.scalalabs.basic.lab04 +import org.joda.time.Duration +import org.junit.runner.RunWith +import org.specs2.mutable.Specification +import org.specs2.runner.JUnitRunner +import org.joda.time._ +import Exercise02._ +import scala.util.parsing.json.JSONObject +/** + * @see ImplictConversionExercise02 + */ +@RunWith(classOf[JUnitRunner]) +class ImplicitConversionExercise02Test extends Specification with DeactivatedTimeConversions { + + "Exercise01" should { + "have a working money DSL" in { + skipped("Uncomment and fix me") +// Euro(2, 0) must be_==~(2 euros) +// Euro(0, 25) must be_==~(25 cents) +// Euro(2, 25) must be_==~(2 euros 25 cents) + } + } + + "Exercise02" should { + import JsonConverter._ + val euro = Euro(1, 2) + val json = JSONObject(Map("symbol" -> "EUR", "amount" -> s"${euro.euros},${euro.cents}")) + "convert Euro to json" in { + val out = convertToJson(euro) + out ==== json + } + "convert json to Euro" in { + val in = parseFromJson[Euro](json) + euro === in + } + } +} + + diff --git a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala deleted file mode 100644 index 87ebd7f3..00000000 --- a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala +++ /dev/null @@ -1,23 +0,0 @@ -package org.scalalabs.basic.lab04 -import org.joda.time.Duration - -import org.junit.runner.RunWith -import org.specs2.mutable.Specification -import org.specs2.runner.JUnitRunner -import org.joda.time._ -/** - * @see ImplictConversionExercise02 - */ -@RunWith(classOf[JUnitRunner]) -class ImplictConversionExercise02Test extends Specification with DeactivatedTimeConversions { - - "Exercise01" should { - "have a working money DSL" in { - skipped("Uncomment and fix me") - // Euro(2, 0) must be_==~(2 euros) - // Euro(0, 25) must be_==~(25 cents) - // Euro(2, 25) must be_==~(2 euros 25 cents) - } - } -} - diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01.scala b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01.scala similarity index 99% rename from solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01.scala rename to solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01.scala index 5493c4f8..47479297 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01.scala @@ -22,7 +22,7 @@ import language.higherKinds * */ -object ImplictConversionExercise01 { +object ImplicitConversionExercise01 { object Exercise01 { def stringToList(s: String): List[Char] = { diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala similarity index 100% rename from solutions/src/main/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02.scala rename to solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01Test.scala b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01Test.scala similarity index 81% rename from solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01Test.scala rename to solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01Test.scala index 027e0c0b..e596b3e1 100644 --- a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise01Test.scala +++ b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise01Test.scala @@ -1,9 +1,9 @@ package org.scalalabs.basic.lab04 -import ImplictConversionExercise01._ -import ImplictConversionExercise01.Exercise01._ -import ImplictConversionExercise01.Exercise02._ -import ImplictConversionExercise01.Exercise03._ -import ImplictConversionExercise01.Exercise04._ +import ImplicitConversionExercise01._ +import ImplicitConversionExercise01.Exercise01._ +import ImplicitConversionExercise01.Exercise02._ +import ImplicitConversionExercise01.Exercise03._ +import ImplicitConversionExercise01.Exercise04._ import org.joda.time.Duration import org.junit.runner.RunWith @@ -14,7 +14,7 @@ import org.joda.time._ * @see ImplictConversionExercise */ @RunWith(classOf[JUnitRunner]) -class ImplictConversionExercise01Test extends Specification with DeactivatedTimeConversions { +class ImplicitConversionExercise01Test extends Specification with DeactivatedTimeConversions { "Exercise01" should { "convert string to list" in { diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala similarity index 100% rename from solutions/src/test/scala/org/scalalabs/basic/lab04/ImplictConversionExercise02Test.scala rename to solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala From 91399b4336b74eb965c2f1715d94e1925b50b020 Mon Sep 17 00:00:00 2001 From: upeter Date: Wed, 16 Apr 2014 18:41:44 +0200 Subject: [PATCH 06/81] Ordering type class exercise added --- .../lab04/ImplicitConversionExercise02.scala | 22 ++++++++++++++----- .../ImplicitConversionExercise02Test.scala | 12 ++++++++-- .../lab04/ImplicitConversionExercise02.scala | 14 ++++++++++-- .../ImplicitConversionExercise02Test.scala | 7 ++++++ 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala index dadf5de9..a745f65a 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala @@ -6,7 +6,9 @@ import language.implicitConversions import language.higherKinds import scala.util.parsing.json.JSONObject -case class Euro(val euros: Int, val cents: Int) +case class Euro(val euros: Int, val cents: Int) { + lazy val inCents: Int = euros * 100 + cents +} object Euro { def fromCents(cents: Int) = new Euro(cents / 100, cents % 100) @@ -35,20 +37,30 @@ trait JsonConverter[T] { object Exercise01 { } + /** * Exercise 2: - * Implement a type class pattern to convert domain objects to and from json. + * Implement Scala's built in Ordering type class for Euro, + * so that the call to Seq(Euro(1,5), Euro(3,2)).sorted compiles. + */ +object Exercise03 { + +} + +/** + * Exercise 3: + * Implement a type class pattern to convert domain objects to and from json. * Take a look at the already defined type class trait @see JsonConverter. * 1. Implement the methods of the JsonCoverter object below that converts domain objects to and from json making use of the JsonConverter type class trait. - * 2. Provide an implementation of the JsonConverter type class trait for the Euro class. + * 2. Provide an implementation of the JsonConverter type class trait for the Euro class. * Place the implementation in the Euro's companion object so that the implicit resolution requires no import. */ object Exercise02 { object JsonConverter { - def convertToJson[T/**provide context bound*/](t: T): JSONObject = { + def convertToJson[T /**provide context bound*/ ](t: T): JSONObject = { ??? } - def parseFromJson[T/**provide context bound*/](json: JSONObject): T = { + def parseFromJson[T /**provide context bound*/ ](json: JSONObject): T = { ??? } } diff --git a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala index 556e1447..21d7c73e 100644 --- a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala +++ b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala @@ -4,7 +4,9 @@ import org.junit.runner.RunWith import org.specs2.mutable.Specification import org.specs2.runner.JUnitRunner import org.joda.time._ +import Exercise01._ import Exercise02._ +import Exercise03._ import scala.util.parsing.json.JSONObject /** * @see ImplictConversionExercise02 @@ -20,8 +22,14 @@ class ImplicitConversionExercise02Test extends Specification with DeactivatedTim // Euro(2, 25) must be_==~(2 euros 25 cents) } } - - "Exercise02" should { + "Exercise02" should { + "make Euro orderable without implementing the Ordered trait" in { + skipped("Uncomment and fix me") +// val raw = Seq(Euro(2, 0), Euro(1, 1), Euro(1, 5)) +// raw.sorted ==== Seq(Euro(1, 1), Euro(1, 5), Euro(2, 0)) + } + } + "Exercise03" should { import JsonConverter._ val euro = Euro(1, 2) val json = JSONObject(Map("symbol" -> "EUR", "amount" -> s"${euro.euros},${euro.cents}")) diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala index 7f47293a..fee0861c 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala @@ -9,7 +9,9 @@ import scala.util.control._ object ImplicitConversionExercises02 { - case class Euro(val euros: Int, val cents: Int) + case class Euro(val euros: Int, val cents: Int) { + lazy val inCents: Int = euros * 100 + cents + } object Euro { def fromCents(cents: Int) = new Euro(cents / 100, cents % 100) @@ -53,6 +55,15 @@ object ImplicitConversionExercises02 { * ======================================================= */ object Exercise02 { + implicit object OrderedEuro extends Ordering[Euro] { + def compare(x: Euro, y: Euro): Int = x.inCents - y.inCents + } + } + + /** + * ======================================================= + */ + object Exercise03 { object JsonConverter { def convertToJson[T: JsonConverter](t: T): JSONObject = { @@ -62,6 +73,5 @@ object ImplicitConversionExercises02 { implicitly[JsonConverter[T]].fromJson(json) } } - } } diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala index 6aae9999..3772f6f0 100644 --- a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala +++ b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala @@ -2,6 +2,7 @@ package org.scalalabs.basic.lab04 import ImplicitConversionExercises02._ import ImplicitConversionExercises02.Exercise01._ import ImplicitConversionExercises02.Exercise02._ +import ImplicitConversionExercises02.Exercise03._ import org.joda.time.Duration import org.junit.runner.RunWith import org.specs2.mutable.Specification @@ -24,6 +25,12 @@ class ImplictConversionExercise02Test extends Specification with DeactivatedTime } } "Exercise02" should { + "make Euro orderable without implementing the Ordered trait" in { + val raw = Seq(Euro(2, 0), Euro(1, 1), Euro(1, 5)) + raw.sorted ==== Seq(Euro(1, 1), Euro(1, 5), Euro(2, 0)) + } + } + "Exercise03" should { import JsonConverter._ val euro = Euro(1, 2) val json = JSONObject(Map("symbol" -> "EUR", "amount" -> s"${euro.euros},${euro.cents}")) From 59e3403555c61f7f1455202c92df2c38235ed57e Mon Sep 17 00:00:00 2001 From: upeter Date: Wed, 16 Apr 2014 18:42:20 +0200 Subject: [PATCH 07/81] function solution for Option exercise added --- .../main/scala/org/scalalabs/basic/lab03/OptionExercise.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab03/OptionExercise.scala b/solutions/src/main/scala/org/scalalabs/basic/lab03/OptionExercise.scala index f21ccc99..bfb57291 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab03/OptionExercise.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab03/OptionExercise.scala @@ -44,6 +44,9 @@ object OptionExercise02 { * to convert a possible numeric String (e.g. Some("12")) to an integer */ def totalPeopleInRooms(rooms:Map[Int,Option[String]]): Int = { + //functional solution + rooms.values.map(i => Exception.allCatch.opt(i.get.toInt)).flatten.sum + val res = for { occupationOpt <- rooms.values occupation <- occupationOpt From af0fc000e0c77c9a75208a6d932755a3f7a75eca Mon Sep 17 00:00:00 2001 From: upeter Date: Wed, 18 Jun 2014 21:18:40 +0200 Subject: [PATCH 08/81] foldLeft exercise --- .../basic/lab02/CollectionExercise.scala | 23 +++++++++++- .../basic/lab02/CollectionExerciseTest.scala | 8 ++++ .../basic/lab02/CollectionExercise.scala | 37 +++++++++++++++++-- .../basic/lab02/CollectionExerciseTest.scala | 8 ++++ 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala b/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala index b58da89a..964be073 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala @@ -65,7 +65,7 @@ object CollectionExercise03 { * checkValuesIncrease(Seq(1,2,2)) == false */ def checkValuesIncrease[T <% Ordered[T]](seq: Seq[T]): Boolean = - error("fix me") + error("fix me") } /*========================================================== */ @@ -80,6 +80,27 @@ object CollectionExercise04 { } } +/*========================================================== */ + +object CollectionExercise05 { + /** + * Filter all even numbers of the given sequence using foldLeft. + * E.g. Seq(1,2,3) is Seq(2) + */ + def filterWithFoldLeft(seq: Seq[Int]): Seq[Int] = { + error("fix me") + } + + /** + * Group all numbers based on whether they are even or odd using foldLeft. + * For even use 'true' for odd use 'false'. + * E.g: Seq(1,2,3) is Map(0 -> Seq(2), 1 -> Seq(1,3)) + */ + def groupByWithFoldLeft(seq: Seq[Int]): Map[Boolean, Seq[Int]] = { + error("fix me") + } +} + diff --git a/labs/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala b/labs/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala index 35864f47..3622441b 100644 --- a/labs/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala +++ b/labs/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala @@ -60,5 +60,13 @@ class CollectionExerciseTest extends Specification { "ullamcorperano".length() === result } } + + "CollectionExercise05" should { + "use foldLeft for common higher order functions" in { + val input = Seq(1, 2, 3) + input.filter(_ % 2 == 0) ==== CollectionExercise05.filterWithFoldLeft(input) + input.groupBy(_ % 2 == 0) ==== CollectionExercise05.groupByWithFoldLeft(input) + } + } } diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala b/solutions/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala index e83d2491..24058698 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala @@ -39,9 +39,9 @@ object CollectionExercise01 { val alphabet = 'a' to 'z' val missingIn = alphabet filterNot (input contains _) alphabet diff input - + val missingOut = alphabet filterNot (output contains _) - alphabet diff output + alphabet diff output //z and q, hint says z -> q, so remaining is: q -> z //visualize missing chars in alphabet @@ -51,8 +51,8 @@ object CollectionExercise01 { //compute mapping val initialMapping = (input zip output).toSet //ensure 1 to 1 mapping - initialMapping.groupBy(_._1).values.forall(_.size == 1 ) - + initialMapping.groupBy(_._1).values.forall(_.size == 1) + val mapper = Map('z' -> 'q', 'q' -> 'z', ' ' -> ' ').withDefaultValue('?') ++ initialMapping lines.map(_ map mapper) @@ -105,9 +105,38 @@ object CollectionExercise04 { */ def calcLengthLongestWord(lines: String*): Int = { lines.map(_.split(" ").map(_.length).max).max + //or: + //lines.flatMap(_.split(" ").map(_.length)).max } +} +object CollectionExercise05 { + /** + * Filter all even numbers of the given sequence using foldLeft. + * E.g. Seq(1,2,3) is Seq(2) + */ + def filterWithFoldLeft(seq: Seq[Int]): Seq[Int] = { + seq.foldLeft(Seq.empty[Int])((cum, i) => if (i % 2 == 0) cum :+ i else cum) + } + /** + * Group all numbers based on whether they are even or odd using foldLeft. + * For even use 'true' for odd use 'false'. + * E.g: Seq(1,2,3) is Map(0 -> Seq(2), 1 -> Seq(1,3)) + */ + def groupByWithFoldLeft(seq: Seq[Int]): Map[Boolean, Seq[Int]] = { + seq.foldLeft(Map[Boolean, Seq[Int]]()) { (map, next) => + val key = next % 2 == 0 + map + (key -> (map.getOrElse(key, Seq()) :+ next)) + } + //simpler + seq.foldLeft(Map[Boolean, Seq[Int]]().withDefaultValue(Seq[Int]())) { (map, next) => + val key = next % 2 == 0 + map + (key -> (map(key) :+ next)) + } + + } } + diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala b/solutions/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala index 845eec99..ac84d8af 100644 --- a/solutions/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala +++ b/solutions/src/test/scala/org/scalalabs/basic/lab02/CollectionExerciseTest.scala @@ -58,5 +58,13 @@ class CollectionExerciseTest extends Specification { "ullamcorperano".length() === result } } + + "CollectionExercise05" should { + "use foldLeft for common higher order functions" in { + val input = Seq(1, 2, 3) + input.filter(_ % 2 == 0) ==== CollectionExercise05.filterWithFoldLeft(input) + input.groupBy(_ % 2 == 0) ==== CollectionExercise05.groupByWithFoldLeft(input) + } + } } From 10ec1caf5b9ad73280b2200b4b11bd90a9754a04 Mon Sep 17 00:00:00 2001 From: upeter Date: Thu, 19 Jun 2014 20:11:35 +0200 Subject: [PATCH 09/81] Moved to Scala 2.11.1, removed JSONObject --- labs/build.sbt | 37 +++++++++------- .../lab04/ImplicitConversionExercise02.scala | 43 +++++++++++++------ .../ImplicitConversionExercise02Test.scala | 21 ++++----- solutions/build.sbt | 13 ++++-- .../lab04/ImplicitConversionExercise02.scala | 33 ++++++++------ .../ImplicitConversionExercise02Test.scala | 5 ++- 6 files changed, 94 insertions(+), 58 deletions(-) diff --git a/labs/build.sbt b/labs/build.sbt index 53bb2efc..eff20ae4 100644 --- a/labs/build.sbt +++ b/labs/build.sbt @@ -1,25 +1,32 @@ name := "ScalaLabs" -organization := "Xebia B.V." - version := "1.0" -scalaVersion := "2.10.2" +scalaVersion := "2.11.1" + +scalacOptions ++= Seq("-unchecked", "-deprecation") resolvers ++= Seq("Local Maven Repository" at "file://"+Path.userHome+"/.m2/repository", - "Signpost releases" at "https://oss.sonatype.org/content/repositories/signpost-releases/") + "Signpost releases" at "https://oss.sonatype.org/content/repositories/signpost-releases/") + +// You should be able to use the following to read all dependencies from the pom.xml file, but somehow those aren't picked up. +// see: https://github.com/harrah/xsbt/wiki/Library-Management +// externalPom() libraryDependencies ++= Seq("joda-time" % "joda-time" % "1.6", - "org.apache.httpcomponents" % "httpclient" % "4.1.1", - "javax.persistence" % "persistence-api" % "1.0", - "org.scala-libs" %% "scalajpa" % "1.4", - "oauth.signpost" % "signpost-core" % "1.2", - "oauth.signpost" % "signpost-commonshttp4" % "1.2", + "org.apache.httpcomponents" % "httpclient" % "4.1.1", + "javax.persistence" % "persistence-api" % "1.0", + "org.scala-libs" %% "scalajpa" % "1.5", + "oauth.signpost" % "signpost-core" % "1.2", + "oauth.signpost" % "signpost-commonshttp4" % "1.2", "org.scala-lang" % "scala-actors" % "2.10.3", - "org.scalatest" %% "scalatest" % "2.0" % "test", - "org.specs2" %% "specs2" % "2.3.7" % "test", - "junit" % "junit" % "4.7" % "test", - "hsqldb" % "hsqldb" % "1.8.0.1" % "test", - "org.hibernate" % "hibernate-entitymanager" % "3.4.0.GA", - "org.slf4j" % "slf4j-simple" % "1.4.2") + "org.scalatest" %% "scalatest" % "2.2.0" % "test", + "org.specs2" %% "specs2" % "2.3.11" % "test", + "org.scala-lang.modules" %% "scala-xml" % "1.0.2", + "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.1", + "org.json4s" %% "json4s-native" % "3.2.9", + "junit" % "junit" % "4.7" % "test", + "hsqldb" % "hsqldb" % "1.8.0.1" % "test", + "org.hibernate" % "hibernate-entitymanager" % "3.4.0.GA", + "org.slf4j" % "slf4j-simple" % "1.4.2") diff --git a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala index a745f65a..5f94febf 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala @@ -4,7 +4,10 @@ import org.joda.time.{ Duration, DateTime } import scala.math._ import language.implicitConversions import language.higherKinds -import scala.util.parsing.json.JSONObject +import org.json4s._ +import org.json4s.JsonDSL._ +import org.json4s.native.JsonMethods._ +import scala.util.control._ case class Euro(val euros: Int, val cents: Int) { lazy val inCents: Int = euros * 100 + cents @@ -14,13 +17,6 @@ object Euro { def fromCents(cents: Int) = new Euro(cents / 100, cents % 100) } -/** - * Only used for exercise2! - */ -trait JsonConverter[T] { - def toJSON(t: T): JSONObject - def fromJson(json: JSONObject): T -} /** * Exercise 1: * Create a money DSL which allows you to create Euro classes as follows: @@ -40,7 +36,7 @@ object Exercise01 { /** * Exercise 2: - * Implement Scala's built in Ordering type class for Euro, + * Implement Scala's built in Ordering type class for Euro, * so that the call to Seq(Euro(1,5), Euro(3,2)).sorted compiles. */ object Exercise03 { @@ -52,19 +48,40 @@ object Exercise03 { * Implement a type class pattern to convert domain objects to and from json. * Take a look at the already defined type class trait @see JsonConverter. * 1. Implement the methods of the JsonCoverter object below that converts domain objects to and from json making use of the JsonConverter type class trait. - * 2. Provide an implementation of the JsonConverter type class trait for the Euro class. - * Place the implementation in the Euro's companion object so that the implicit resolution requires no import. + * 2. Provide an implementation of the JsonConverter type class trait for the Euro class. + * Place the implementation in the Euro's companion object so that the implicit resolution requires no import. + * For marshalling and unmarshalling json make use of the @see EuroJsonMarshallerHelper */ object Exercise02 { object JsonConverter { - def convertToJson[T /**provide context bound*/ ](t: T): JSONObject = { + def convertToJson[T /**provide context bound*/ ](t: T): JValue = { ??? } - def parseFromJson[T /**provide context bound*/ ](json: JSONObject): T = { + def parseFromJson[T /**provide context bound*/ ](json: JValue): T = { ??? } } +/** + * Only used for exercise2! + */ +trait JsonConverter[T] { + def toJSON(t: T): JValue + def fromJson(json: JValue): T +} +/** + * Only used for exercise2! + */ +object EuroJsonMarshallerHelper { + implicit val formats = DefaultFormats + def marshal(e: Euro): JValue = ("symbol" -> "EUR") ~ ("amount" -> s"${e.euros},${e.cents}") + def unmarshal(json: JValue): Euro = { + Exception.allCatch.opt { + val amount = (json \ "amount").extract[String].split(",") + Euro(amount(0).toInt, amount(1).toInt) + } getOrElse (Euro(0, 0)) + } +} } diff --git a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala index 21d7c73e..89b6ec38 100644 --- a/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala +++ b/labs/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala @@ -4,10 +4,11 @@ import org.junit.runner.RunWith import org.specs2.mutable.Specification import org.specs2.runner.JUnitRunner import org.joda.time._ +import org.json4s._ +import org.json4s.JsonDSL._ import Exercise01._ import Exercise02._ import Exercise03._ -import scala.util.parsing.json.JSONObject /** * @see ImplictConversionExercise02 */ @@ -17,22 +18,22 @@ class ImplicitConversionExercise02Test extends Specification with DeactivatedTim "Exercise01" should { "have a working money DSL" in { skipped("Uncomment and fix me") -// Euro(2, 0) must be_==~(2 euros) -// Euro(0, 25) must be_==~(25 cents) -// Euro(2, 25) must be_==~(2 euros 25 cents) + // Euro(2, 0) must be_==~(2 euros) + // Euro(0, 25) must be_==~(25 cents) + // Euro(2, 25) must be_==~(2 euros 25 cents) } - } - "Exercise02" should { + } + "Exercise02" should { "make Euro orderable without implementing the Ordered trait" in { skipped("Uncomment and fix me") -// val raw = Seq(Euro(2, 0), Euro(1, 1), Euro(1, 5)) -// raw.sorted ==== Seq(Euro(1, 1), Euro(1, 5), Euro(2, 0)) + // val raw = Seq(Euro(2, 0), Euro(1, 1), Euro(1, 5)) + // raw.sorted ==== Seq(Euro(1, 1), Euro(1, 5), Euro(2, 0)) } } "Exercise03" should { import JsonConverter._ val euro = Euro(1, 2) - val json = JSONObject(Map("symbol" -> "EUR", "amount" -> s"${euro.euros},${euro.cents}")) + val json = ("symbol" -> "EUR") ~ ("amount" -> s"${euro.euros},${euro.cents}") "convert Euro to json" in { val out = convertToJson(euro) out ==== json @@ -40,7 +41,7 @@ class ImplicitConversionExercise02Test extends Specification with DeactivatedTim "convert json to Euro" in { val in = parseFromJson[Euro](json) euro === in - } + } } } diff --git a/solutions/build.sbt b/solutions/build.sbt index 2c588fa7..a75fc668 100644 --- a/solutions/build.sbt +++ b/solutions/build.sbt @@ -4,7 +4,9 @@ organization := "Xebia B.V." version := "1.0" -scalaVersion := "2.10.2" +scalaVersion := "2.11.1" + +scalacOptions ++= Seq("-unchecked", "-deprecation") resolvers ++= Seq("Local Maven Repository" at "file://"+Path.userHome+"/.m2/repository", "Signpost releases" at "https://oss.sonatype.org/content/repositories/signpost-releases/") @@ -16,12 +18,15 @@ resolvers ++= Seq("Local Maven Repository" at "file://"+Path.userHome+"/.m2/repo libraryDependencies ++= Seq("joda-time" % "joda-time" % "1.6", "org.apache.httpcomponents" % "httpclient" % "4.1.1", "javax.persistence" % "persistence-api" % "1.0", - "org.scala-libs" %% "scalajpa" % "1.4", + "org.scala-libs" %% "scalajpa" % "1.5", "oauth.signpost" % "signpost-core" % "1.2", "oauth.signpost" % "signpost-commonshttp4" % "1.2", "org.scala-lang" % "scala-actors" % "2.10.3", - "org.scalatest" %% "scalatest" % "2.0" % "test", - "org.specs2" %% "specs2" % "2.3.7" % "test", + "org.scalatest" %% "scalatest" % "2.2.0" % "test", + "org.specs2" %% "specs2" % "2.3.11" % "test", + "org.scala-lang.modules" %% "scala-xml" % "1.0.2", + "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.1", + "org.json4s" %% "json4s-native" % "3.2.9", "junit" % "junit" % "4.7" % "test", "hsqldb" % "hsqldb" % "1.8.0.1" % "test", "org.hibernate" % "hibernate-entitymanager" % "3.4.0.GA", diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala index fee0861c..54127523 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala @@ -4,7 +4,8 @@ import org.joda.time.{ Duration, DateTime } import scala.math._ import language.implicitConversions import language.higherKinds -import scala.util.parsing.json.JSONObject +import org.json4s._ +import org.json4s.JsonDSL._ import scala.util.control._ object ImplicitConversionExercises02 { @@ -17,23 +18,27 @@ object ImplicitConversionExercises02 { def fromCents(cents: Int) = new Euro(cents / 100, cents % 100) implicit object EuroAsJsonConverter extends JsonConverter[Euro] { - override def toJSON(e: Euro): JSONObject = JSONObject(Map("symbol" -> "EUR", "amount" -> s"${e.euros},${e.cents}")) - override def fromJson(json: JSONObject): Euro = { - val opt = for { - eurosOpt <- json.obj.get("amount") - amount = eurosOpt.toString.split(",") - (euros, cents) <- Exception.allCatch.opt(amount(0).toInt -> amount(1).toInt) - } yield Euro(euros, cents) - opt.getOrElse(Euro(0, 0)) - } + override def toJSON(e: Euro): JValue = EuroJsonMarshallerHelper.marshal(e) + override def fromJson(json: JValue): Euro = EuroJsonMarshallerHelper.unmarshal(json) + } + } + + object EuroJsonMarshallerHelper { + implicit val formats = DefaultFormats + def marshal(e: Euro): JValue = ("symbol" -> "EUR") ~ ("amount" -> s"${e.euros},${e.cents}") + def unmarshal(json: JValue): Euro = { + Exception.allCatch.opt { + val amount = (json \ "amount").extract[String].split(",") + Euro(amount(0).toInt, amount(1).toInt) + } getOrElse (Euro(0, 0)) } } import annotation.implicitNotFound @implicitNotFound(msg = "Cannot find JsonParser type class for ${T}") trait JsonConverter[T] { - def toJSON(t: T): JSONObject - def fromJson(json: JSONObject): T + def toJSON(t: T): JValue + def fromJson(json: JValue): T } /** @@ -66,10 +71,10 @@ object ImplicitConversionExercises02 { object Exercise03 { object JsonConverter { - def convertToJson[T: JsonConverter](t: T): JSONObject = { + def convertToJson[T: JsonConverter](t: T): JValue = { implicitly[JsonConverter[T]].toJSON(t) } - def parseFromJson[T: JsonConverter](json: JSONObject): T = { + def parseFromJson[T: JsonConverter](json: JValue): T = { implicitly[JsonConverter[T]].fromJson(json) } } diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala index 3772f6f0..0f4b3797 100644 --- a/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala +++ b/solutions/src/test/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02Test.scala @@ -8,7 +8,8 @@ import org.junit.runner.RunWith import org.specs2.mutable.Specification import org.specs2.runner.JUnitRunner import org.joda.time._ -import scala.util.parsing.json.JSONObject +import org.json4s._ +import org.json4s.JsonDSL._ import scala.util.control._ /** @@ -33,7 +34,7 @@ class ImplictConversionExercise02Test extends Specification with DeactivatedTime "Exercise03" should { import JsonConverter._ val euro = Euro(1, 2) - val json = JSONObject(Map("symbol" -> "EUR", "amount" -> s"${euro.euros},${euro.cents}")) + val json = ("symbol" -> "EUR") ~ ("amount" -> s"${euro.euros},${euro.cents}") "convert Euro to json" in { val out = convertToJson(euro) out ==== json From c61a755701f4dc9330b5a1cc34243d5807552198 Mon Sep 17 00:00:00 2001 From: upeter Date: Thu, 19 Jun 2014 20:14:29 +0200 Subject: [PATCH 10/81] Fixed exercise number --- .../basic/lab04/ImplicitConversionExercise02.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala index 5f94febf..eac90aa5 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala @@ -39,7 +39,7 @@ object Exercise01 { * Implement Scala's built in Ordering type class for Euro, * so that the call to Seq(Euro(1,5), Euro(3,2)).sorted compiles. */ -object Exercise03 { +object Exercise02 { } @@ -52,7 +52,7 @@ object Exercise03 { * Place the implementation in the Euro's companion object so that the implicit resolution requires no import. * For marshalling and unmarshalling json make use of the @see EuroJsonMarshallerHelper */ -object Exercise02 { +object Exercise03 { object JsonConverter { def convertToJson[T /**provide context bound*/ ](t: T): JValue = { ??? @@ -63,14 +63,14 @@ object Exercise02 { } /** - * Only used for exercise2! + * Only used for Exercise03! */ trait JsonConverter[T] { def toJSON(t: T): JValue def fromJson(json: JValue): T } /** - * Only used for exercise2! + * Only used for Exercise03! */ object EuroJsonMarshallerHelper { implicit val formats = DefaultFormats From 9cb5e2bf37d30807cedf812e80fc869030eae572 Mon Sep 17 00:00:00 2001 From: upeter Date: Thu, 19 Jun 2014 20:19:56 +0200 Subject: [PATCH 11/81] replace depricated expect with assertResult --- .../lab01/FirstExerciseTest.scala | 36 +++++++++---------- .../lab02/SecondExerciseBonusTest.scala | 12 +++---- .../lab02/SecondExerciseTest.scala | 12 +++---- .../lab03/ThirdExerciseTest.scala | 16 ++++----- .../lab01/FirstExerciseTest.scala | 2 +- .../lab02/SecondExerciseTest.scala | 10 +++--- .../lab03/ThirdExerciseTest.scala | 16 ++++----- 7 files changed, 52 insertions(+), 52 deletions(-) diff --git a/labs/src/test/scala/org/scalalabs/intermediate/lab01/FirstExerciseTest.scala b/labs/src/test/scala/org/scalalabs/intermediate/lab01/FirstExerciseTest.scala index eb032f05..c5e93608 100644 --- a/labs/src/test/scala/org/scalalabs/intermediate/lab01/FirstExerciseTest.scala +++ b/labs/src/test/scala/org/scalalabs/intermediate/lab01/FirstExerciseTest.scala @@ -44,7 +44,7 @@ class FirstExerciseTest extends JUnitSuite { // val tweets = getListOfTweets() // there should be 20 tweets -// expect(20) {tweets.size} +// assertResult(20) {tweets.size} } @Test @@ -53,18 +53,18 @@ class FirstExerciseTest extends JUnitSuite { //TODO uncomment and fix test // val firstTweet = getListOfTweets()(0) // -// expect(3362029699L) {firstTweet.id} +// assertResult(3362029699L) {firstTweet.id} // -// expect(None) {firstTweet.inReplyToStatusId} -// expect(None) {firstTweet.inReplyToUserId} -// expect(false) {firstTweet.truncated} -// expect (false) {firstTweet.favorited} +// assertResult(None) {firstTweet.inReplyToStatusId} +// assertResult(None) {firstTweet.inReplyToUserId} +// assertResult(false) {firstTweet.truncated} +// assertResult (false) {firstTweet.favorited} // -// expect("Having much more fun working on #jaoo talks than yesterday's hard drive crash redddddddcovery.") { +// assertResult("Having much more fun working on #jaoo talks than yesterday's hard drive crash redddddddcovery.") { // firstTweet.text // } // -// expect(twitterDateTimeFormat.parseDateTime("Mon Aug 17 14:19:06 +0000 2009")) { +// assertResult(twitterDateTimeFormat.parseDateTime("Mon Aug 17 14:19:06 +0000 2009")) { // firstTweet.createdAt // } } @@ -75,16 +75,16 @@ class FirstExerciseTest extends JUnitSuite { //TODO uncomment these tests and assertions // val firstTweetUser: TwitterUser = getListOfTweets()(0).user // -// expect(16665197L) {firstTweetUser.id} -// expect("Martin Fowler") {firstTweetUser.name} -// expect("martinfowler") {firstTweetUser.screen_name} -// expect("Loud Mouth, ThoughtWorks") {firstTweetUser.description} -// expect("Boston") {firstTweetUser.location} -// expect("http://www.martinfowler.com/") {firstTweetUser.url} -// expect("http://a3.twimg.com/profile_images/79787739/mf-tg-sq_normal.jpg") {firstTweetUser.profileImageUrl} -// expect(787) {firstTweetUser.statusesCount} -// expect(166) {firstTweetUser.friendsCount} -// expect(8735) {firstTweetUser.followersCount} +// assertResult(16665197L) {firstTweetUser.id} +// assertResult("Martin Fowler") {firstTweetUser.name} +// assertResult("martinfowler") {firstTweetUser.screen_name} +// assertResult("Loud Mouth, ThoughtWorks") {firstTweetUser.description} +// assertResult("Boston") {firstTweetUser.location} +// assertResult("http://www.martinfowler.com/") {firstTweetUser.url} +// assertResult("http://a3.twimg.com/profile_images/79787739/mf-tg-sq_normal.jpg") {firstTweetUser.profileImageUrl} +// assertResult(787) {firstTweetUser.statusesCount} +// assertResult(166) {firstTweetUser.friendsCount} +// assertResult(8735) {firstTweetUser.followersCount} } } \ No newline at end of file diff --git a/labs/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseBonusTest.scala b/labs/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseBonusTest.scala index af534184..3a58d58d 100644 --- a/labs/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseBonusTest.scala +++ b/labs/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseBonusTest.scala @@ -37,7 +37,7 @@ class SecondExerciseBonusTest extends JUnitSuite { def testFindPopularFriends() { // TwitterUsers are popular if they have at least 2000 followers fail("TODO: uncomment and fix") -// expect(10) { +// assertResult(10) { // getFriends.thatArePopular.size // } } @@ -45,7 +45,7 @@ class SecondExerciseBonusTest extends JUnitSuite { @Test def testFindScreenNamesOfPopularFriends() { fail("TODO: uncomment and fix") -// expect(List("headius", "twitterapi", "stephenfry", "macrumors", "spolsky", "martinfowler", "WardCunningham", "unclebobmartin", "pragdave", "KentBeck")) { +// assertResult(List("headius", "twitterapi", "stephenfry", "macrumors", "spolsky", "martinfowler", "WardCunningham", "unclebobmartin", "pragdave", "KentBeck")) { // getFriends thatArePopularByScreenName // } } @@ -54,16 +54,16 @@ class SecondExerciseBonusTest extends JUnitSuite { @Test def testFindScreenNamesOfPupularFriendsSortedByPopularity() { fail("TODO: uncomment and fix") -// expect(List("stephenfry", "macrumors", "twitterapi", "spolsky", "martinfowler", "KentBeck", "unclebobmartin", "pragdave", "WardCunningham", "headius")) { +// assertResult(List("stephenfry", "macrumors", "twitterapi", "spolsky", "martinfowler", "KentBeck", "unclebobmartin", "pragdave", "WardCunningham", "headius")) { // getFriends thatArePopularByScreenNameSortedbyPopularity // } } - // We expect a List[(String, Int)], i.e. a List of tuples, each with a screen name and a number of followers + // We assertResult a List[(String, Int)], i.e. a List of tuples, each with a screen name and a number of followers @Test def testFindPopularFriendsAndTheirRankings() { fail("TODO: uncomment and fix") -// expect( +// assertResult( // List(("stephenfry", 714779), // ("macrumors", 74132), // ("twitterapi", 18817), @@ -83,7 +83,7 @@ class SecondExerciseBonusTest extends JUnitSuite { @Test def testFindFriendsThatAreAlsoFollowers() { fail("TODO: uncomment and fix") -// expect(10) { +// assertResult(10) { // getFriends.thatAreAlsoIn(getFollowers).size // } } diff --git a/labs/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseTest.scala b/labs/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseTest.scala index efa36e48..29dc7051 100644 --- a/labs/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseTest.scala +++ b/labs/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseTest.scala @@ -37,7 +37,7 @@ class SecondExerciseTest extends JUnitSuite { def testFindPopularFriends() { // TwitterUsers are popular if they have at least 2000 followers fail("TODO uncomment and fix") -// expect(10) { +// assertResult(10) { // TwitterUsers.thatArePopular(getFriends()).size // } } @@ -50,7 +50,7 @@ class SecondExerciseTest extends JUnitSuite { fail("TODO uncomment and fix") // import scala.{TwitterUsers => Friends} // -// expect(List("headius", "twitterapi", "stephenfry", "macrumors", "spolsky", "martinfowler", "WardCunningham", "unclebobmartin", "pragdave", "KentBeck")) { +// assertResult(List("headius", "twitterapi", "stephenfry", "macrumors", "spolsky", "martinfowler", "WardCunningham", "unclebobmartin", "pragdave", "KentBeck")) { // Friends.thatArePopularByScreenName(getFriends) // } } @@ -59,16 +59,16 @@ class SecondExerciseTest extends JUnitSuite { @Test def testFindScreenNamesOfPupularFriendsSortedByPopularity() { fail("TODO uncomment and fix") -// expect(List("stephenfry", "macrumors", "twitterapi", "spolsky", "martinfowler", "KentBeck", "unclebobmartin", "pragdave", "WardCunningham", "headius")) { +// assertResult(List("stephenfry", "macrumors", "twitterapi", "spolsky", "martinfowler", "KentBeck", "unclebobmartin", "pragdave", "WardCunningham", "headius")) { // TwitterUsers.thatArePopularByScreenNameSortedbyPopularity(getFriends) // } } - // We expect a List[(String, Int)], i.e. a List of tuples, each with a screen name and a number of followers + // We assertResult a List[(String, Int)], i.e. a List of tuples, each with a screen name and a number of followers @Test def testFindPopularFriendsAndTheirRankings() { fail("TODO: uncomment and fix") -// expect( +// assertResult( // List(("stephenfry", 714779), // ("macrumors", 74132), // ("twitterapi", 18817), @@ -88,7 +88,7 @@ class SecondExerciseTest extends JUnitSuite { @Test def testFindFriendsThatAreAlsoFollowers() { fail("TODO: uncomment and fix") -// expect(10) { +// assertResult(10) { // TwitterUsers.thatAreInBothLists(getFriends, getFollowers).size // } } diff --git a/labs/src/test/scala/org/scalalabs/intermediate/lab03/ThirdExerciseTest.scala b/labs/src/test/scala/org/scalalabs/intermediate/lab03/ThirdExerciseTest.scala index 8146c0ab..40a00010 100644 --- a/labs/src/test/scala/org/scalalabs/intermediate/lab03/ThirdExerciseTest.scala +++ b/labs/src/test/scala/org/scalalabs/intermediate/lab03/ThirdExerciseTest.scala @@ -55,8 +55,8 @@ class ThirdExerciseTest extends JUnitSuite { // val twitter:UnauthenticatedSession = TwitterSession() // val publicTimeline:TwitterTimeline = twitter.publicTimeline // -// expect(20) {publicTimeline.toList.size} -// expect(true) {publicTimeline.forall(_.user != null)} +// assertResult(20) {publicTimeline.toList.size} +// assertResult(true) {publicTimeline.forall(_.user != null)} } @Test @@ -65,7 +65,7 @@ class ThirdExerciseTest extends JUnitSuite { // val twitter:AuthenticatedSession = TwitterSession(testAuthInfo) // val friendsTimeline = twitter.friendsTimeline // -// expect(true) {friendsTimeline.forall(_.user != null)} +// assertResult(true) {friendsTimeline.forall(_.user != null)} } @Test @@ -76,7 +76,7 @@ class ThirdExerciseTest extends JUnitSuite { // val friendsTimeline = twitter.friendsTimeline // val friends:TwitterUsers = twitter.friends // -// expect(true) {friendsTimeline.forall(tweet => friends.exists(_ == tweet.user) || testAccountUsername == tweet.user.screenName)} +// assertResult(true) {friendsTimeline.forall(tweet => friends.exists(_ == tweet.user) || testAccountUsername == tweet.user.screenName)} } @Test @@ -85,7 +85,7 @@ class ThirdExerciseTest extends JUnitSuite { // val twitter:UnauthenticatedSession = TwitterSession() // val userTimeline:TwitterTimeline = twitter.userTimeline("sgrijpink") // -// expect(true) {userTimeline.forall(_.user.screenName == "sgrijpink")} +// assertResult(true) {userTimeline.forall(_.user.screenName == "sgrijpink")} } @Test @@ -94,7 +94,7 @@ class ThirdExerciseTest extends JUnitSuite { // val twitter:AuthenticatedSession = TwitterSession(testAuthInfo) // val userTimeline:TwitterTimeline = twitter.userTimeline(testAccountUsername) // -// expect(true) {userTimeline.forall(_.user.screenName == testAccountUsername)} +// assertResult(true) {userTimeline.forall(_.user.screenName == testAccountUsername)} } // Bonus exercise !!! @@ -112,8 +112,8 @@ class ThirdExerciseTest extends JUnitSuite { // you will recognize. // val tweet = twitter.tweet(baseText + random.nextLong); // -// expect(testAccountUsername) {tweet.user.screenName} -// expect(true) {tweet.text.contains(baseText)} +// assertResult(testAccountUsername) {tweet.user.screenName} +// assertResult(true) {tweet.text.contains(baseText)} // } } \ No newline at end of file diff --git a/solutions/src/test/scala/org/scalalabs/intermediate/lab01/FirstExerciseTest.scala b/solutions/src/test/scala/org/scalalabs/intermediate/lab01/FirstExerciseTest.scala index 089d3421..85d867ad 100644 --- a/solutions/src/test/scala/org/scalalabs/intermediate/lab01/FirstExerciseTest.scala +++ b/solutions/src/test/scala/org/scalalabs/intermediate/lab01/FirstExerciseTest.scala @@ -50,7 +50,7 @@ class FirstExerciseTest extends JUnitSuite { assertResult(None) {firstTweet.inReplyToStatusId} assertResult(None) {firstTweet.inReplyToUserId} assertResult(false) {firstTweet.truncated} - expect (false) {firstTweet.favorited} + assertResult(false) {firstTweet.favorited} assertResult("Having much more fun working on #jaoo talks than yesterday's hard drive crash recovery.") { firstTweet.text diff --git a/solutions/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseTest.scala b/solutions/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseTest.scala index 6ccd7de9..8b69004c 100644 --- a/solutions/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseTest.scala +++ b/solutions/src/test/scala/org/scalalabs/intermediate/lab02/SecondExerciseTest.scala @@ -34,7 +34,7 @@ class SecondExerciseTest extends JUnitSuite { @Test def testFindPopularFriends() { // TwitterUsers are popular if they have at least 2000 followers - expect(10) { + assertResult(10) { TwitterUsers.thatArePopular(getFriends()).size } } @@ -46,7 +46,7 @@ class SecondExerciseTest extends JUnitSuite { // simply because we can). import org.scalalabs.intermediate.lab02.{TwitterUsers => Friends} - expect(List("headius", "twitterapi", "stephenfry", "macrumors", "spolsky", "martinfowler", "WardCunningham", "unclebobmartin", "pragdave", "KentBeck")) { + assertResult(List("headius", "twitterapi", "stephenfry", "macrumors", "spolsky", "martinfowler", "WardCunningham", "unclebobmartin", "pragdave", "KentBeck")) { Friends.thatArePopularByScreenName(getFriends) } } @@ -54,7 +54,7 @@ class SecondExerciseTest extends JUnitSuite { // the same List[String] as last time but now sorted by followersCount (highest first) @Test def testFindScreenNamesOfPupularFriendsSortedByPopularity() { - expect(List("stephenfry", "macrumors", "twitterapi", "spolsky", "martinfowler", "KentBeck", "unclebobmartin", "pragdave", "WardCunningham", "headius")) { + assertResult(List("stephenfry", "macrumors", "twitterapi", "spolsky", "martinfowler", "KentBeck", "unclebobmartin", "pragdave", "WardCunningham", "headius")) { TwitterUsers.thatArePopularByScreenNameSortedbyPopularity(getFriends) } } @@ -62,7 +62,7 @@ class SecondExerciseTest extends JUnitSuite { // We expect a List[(String, Int)], i.e. a List of tuples, each with a screen name and a number of followers @Test def testFindPopularFriendsAndTheirRankings() { - expect( + assertResult( List(("stephenfry", 714779), ("macrumors", 74132), ("twitterapi", 18817), @@ -81,7 +81,7 @@ class SecondExerciseTest extends JUnitSuite { // Hint: you might want to implement equals and hashcode for this one @Test def testFindFriendsThatAreAlsoFollowers() { - expect(10) { + assertResult(10) { TwitterUsers.thatAreInBothLists(getFriends, getFollowers).size } } diff --git a/solutions/src/test/scala/org/scalalabs/intermediate/lab03/ThirdExerciseTest.scala b/solutions/src/test/scala/org/scalalabs/intermediate/lab03/ThirdExerciseTest.scala index 51c80f46..0602b682 100644 --- a/solutions/src/test/scala/org/scalalabs/intermediate/lab03/ThirdExerciseTest.scala +++ b/solutions/src/test/scala/org/scalalabs/intermediate/lab03/ThirdExerciseTest.scala @@ -53,8 +53,8 @@ class ThirdExerciseTest extends JUnitSuite { val twitter: UnauthenticatedSession = TwitterSession() val publicTimeline: TwitterTimeline = twitter.publicTimeline - expect(20) { publicTimeline.toList.size } - expect(true) { publicTimeline.forall(_.user != null) } + assertResult(20) { publicTimeline.toList.size } + assertResult(true) { publicTimeline.forall(_.user != null) } } @Test @@ -63,7 +63,7 @@ class ThirdExerciseTest extends JUnitSuite { val twitter: AuthenticatedSession = TwitterSession(testAuthInfo) val friendsTimeline = twitter.friendsTimeline - expect(true) { friendsTimeline.forall(_.user != null) } + assertResult(true) { friendsTimeline.forall(_.user != null) } } @Test @@ -74,7 +74,7 @@ class ThirdExerciseTest extends JUnitSuite { val friendsTimeline = twitter.friendsTimeline val friends: TwitterUsers = twitter.friends - expect(true) { friendsTimeline.forall(tweet => friends.exists(_ == tweet.user) || testAccountUsername == tweet.user.screenName) } + assertResult(true) { friendsTimeline.forall(tweet => friends.exists(_ == tweet.user) || testAccountUsername == tweet.user.screenName) } } @Test @@ -83,7 +83,7 @@ class ThirdExerciseTest extends JUnitSuite { val twitter: UnauthenticatedSession = TwitterSession() val userTimeline: TwitterTimeline = twitter.userTimeline("sgrijpink") - expect(true) { userTimeline.forall(_.user.screenName == "sgrijpink") } + assertResult(true) { userTimeline.forall(_.user.screenName == "sgrijpink") } } @Test @@ -92,7 +92,7 @@ class ThirdExerciseTest extends JUnitSuite { val twitter: AuthenticatedSession = TwitterSession(testAuthInfo) val userTimeline: TwitterTimeline = twitter.userTimeline(testAccountUsername) - expect(true) { userTimeline.forall(_.user.screenName == testAccountUsername) } + assertResult(true) { userTimeline.forall(_.user.screenName == testAccountUsername) } } // Bonus exercise !!! @@ -108,8 +108,8 @@ class ThirdExerciseTest extends JUnitSuite { // sensitive are more than welcome. val tweet = twitter.tweet(baseText + System.getProperty("user.name") + " on " + System.currentTimeMillis()) - expect(testAccountUsername) { tweet.user.screenName } - expect(true) { tweet.text.startsWith(baseText) } + assertResult(testAccountUsername) { tweet.user.screenName } + assertResult(true) { tweet.text.startsWith(baseText) } } } \ No newline at end of file From 88efd86f67ef3eb00109cc3d6d41aeb7beb3d5db Mon Sep 17 00:00:00 2001 From: upeter Date: Thu, 19 Jun 2014 20:45:55 +0200 Subject: [PATCH 12/81] Migration pom files to Scala 2.11.1 --- labs/pom.xml | 168 ++++++++++++++++++++++++--------------------- solutions/pom.xml | 171 ++++++++++++++++++++++++---------------------- 2 files changed, 181 insertions(+), 158 deletions(-) diff --git a/labs/pom.xml b/labs/pom.xml index 5db3736e..95064e50 100644 --- a/labs/pom.xml +++ b/labs/pom.xml @@ -10,7 +10,7 @@ 2009 - 2.10.2 + 2.11.1 @@ -55,21 +55,21 @@ scala-library ${scala.version} - - org.apache.httpcomponents - httpclient - 4.0 - - - org.apache.httpcomponents - httpcore - 4.0 - - - net.jcip - jcip-annotations - 1.0 - + + org.apache.httpcomponents + httpclient + 4.0 + + + org.apache.httpcomponents + httpcore + 4.0 + + + net.jcip + jcip-annotations + 1.0 + joda-time @@ -78,31 +78,43 @@ - org.scalatest - scalatest_2.10 - 2.0 - test + org.scalatest + scalatest_2.11 + 2.2.0 + test + - org.scala-lang - scala-reflect - 2.10.2 - - - org.scala-lang - scala-actors - 2.10.2 - - - org.specs2 - specs2_2.10 - 2.3.7 - test - + org.scala-lang + scala-actors + 2.11.1 + - junit - junit + org.scala-lang.modules + scala-xml_2.11 + 1.0.2 + + + org.scala-lang.modules + scala-parser-combinators_2.11 + 1.0.1 + + + org.json4s + json4s-native_2.11 + 3.2.9 + + + org.specs2 + specs2_2.11 + 2.3.12 + test + + + junit + junit 4.7 test @@ -114,10 +126,10 @@ org.scala-libs - scalajpa_2.10 - 1.4 + scalajpa_2.11 + 1.5 - + geronimo-spec geronimo-spec-ejb @@ -145,19 +157,19 @@ slf4j-simple 1.4.2 runtime - - - oauth.signpost - signpost-core - 1.2 - compile - - - oauth.signpost - signpost-commonshttp4 - 1.2 - compile - + + + oauth.signpost + signpost-core + 1.2 + compile + + + oauth.signpost + signpost-commonshttp4 + 1.2 + compile + @@ -175,33 +187,33 @@ org.scala-tools maven-scala-plugin - 2.10.1 + 2.14.1 + + + + + compile + + compile + + compile + + + test-compile + + testCompile + + test-compile + - - - compile - - compile - - compile - - - - test-compile - - testCompile - - test-compile - - - - process-resources - - compile - - - + + process-resources + + compile + + + -Xmx1024m diff --git a/solutions/pom.xml b/solutions/pom.xml index 57673664..40e0b7e7 100644 --- a/solutions/pom.xml +++ b/solutions/pom.xml @@ -1,5 +1,4 @@ - 4.0.0 org.scalalabs @@ -10,7 +9,7 @@ 2009 - 2.10.2 + 2.11.1 @@ -55,21 +54,21 @@ scala-library ${scala.version} - - org.apache.httpcomponents - httpclient - 4.0 - - - org.apache.httpcomponents - httpcore - 4.0 - - - net.jcip - jcip-annotations - 1.0 - + + org.apache.httpcomponents + httpclient + 4.0 + + + org.apache.httpcomponents + httpcore + 4.0 + + + net.jcip + jcip-annotations + 1.0 + joda-time @@ -78,31 +77,43 @@ - org.scalatest - scalatest_2.10 - 2.0 - test + org.scalatest + scalatest_2.11 + 2.2.0 + test + - org.scala-lang - scala-reflect - 2.10.2 - - - org.scala-lang - scala-actors - 2.10.2 - - - org.specs2 - specs2_2.10 - 2.3.7 - test - + org.scala-lang + scala-actors + 2.11.1 + - junit - junit + org.scala-lang.modules + scala-xml_2.11 + 1.0.2 + + + org.scala-lang.modules + scala-parser-combinators_2.11 + 1.0.1 + + + org.json4s + json4s-native_2.11 + 3.2.9 + + + org.specs2 + specs2_2.11 + 2.3.12 + test + + + junit + junit 4.7 test @@ -114,10 +125,10 @@ org.scala-libs - scalajpa_2.10 - 1.4 + scalajpa_2.11 + 1.5 - + geronimo-spec geronimo-spec-ejb @@ -145,19 +156,19 @@ slf4j-simple 1.4.2 runtime - - - oauth.signpost - signpost-core - 1.2 - compile - - - oauth.signpost - signpost-commonshttp4 - 1.2 - compile - + + + oauth.signpost + signpost-core + 1.2 + compile + + + oauth.signpost + signpost-commonshttp4 + 1.2 + compile + @@ -175,33 +186,33 @@ org.scala-tools maven-scala-plugin - 2.10.1 + 2.14.1 + + + + + compile + + compile + + compile + + + test-compile + + testCompile + + test-compile + - - - compile - - compile - - compile - - - - test-compile - - testCompile - - test-compile - - - - process-resources - - compile - - - + + process-resources + + compile + + + -Xmx1024m From cb8672d0b6b963214c916eef794b92ecbb1eabaa Mon Sep 17 00:00:00 2001 From: upeter Date: Thu, 19 Jun 2014 20:52:08 +0200 Subject: [PATCH 13/81] dependency fix for actors --- labs/build.sbt | 4 ++-- solutions/build.sbt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/labs/build.sbt b/labs/build.sbt index eff20ae4..b4f85b7e 100644 --- a/labs/build.sbt +++ b/labs/build.sbt @@ -19,9 +19,9 @@ libraryDependencies ++= Seq("joda-time" % "joda-time" % "1.6", "org.scala-libs" %% "scalajpa" % "1.5", "oauth.signpost" % "signpost-core" % "1.2", "oauth.signpost" % "signpost-commonshttp4" % "1.2", - "org.scala-lang" % "scala-actors" % "2.10.3", + "org.scala-lang" % "scala-actors" % "2.11.1", "org.scalatest" %% "scalatest" % "2.2.0" % "test", - "org.specs2" %% "specs2" % "2.3.11" % "test", + "org.specs2" %% "specs2" % "2.3.12" % "test", "org.scala-lang.modules" %% "scala-xml" % "1.0.2", "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.1", "org.json4s" %% "json4s-native" % "3.2.9", diff --git a/solutions/build.sbt b/solutions/build.sbt index a75fc668..8a1d08cd 100644 --- a/solutions/build.sbt +++ b/solutions/build.sbt @@ -21,9 +21,9 @@ libraryDependencies ++= Seq("joda-time" % "joda-time" % "1.6", "org.scala-libs" %% "scalajpa" % "1.5", "oauth.signpost" % "signpost-core" % "1.2", "oauth.signpost" % "signpost-commonshttp4" % "1.2", - "org.scala-lang" % "scala-actors" % "2.10.3", + "org.scala-lang" % "scala-actors" % "2.11.1", "org.scalatest" %% "scalatest" % "2.2.0" % "test", - "org.specs2" %% "specs2" % "2.3.11" % "test", + "org.specs2" %% "specs2" % "2.3.12" % "test", "org.scala-lang.modules" %% "scala-xml" % "1.0.2", "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.1", "org.json4s" %% "json4s-native" % "3.2.9", From dd6a722eacf1191cc847eb9b2e47038ea87100fe Mon Sep 17 00:00:00 2001 From: upeter Date: Fri, 15 Aug 2014 08:58:06 +0200 Subject: [PATCH 14/81] Adjusted partial function exercise to make test run --- .../org/scalalabs/basic/lab03/PatternMatchingExercise.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab03/PatternMatchingExercise.scala b/labs/src/main/scala/org/scalalabs/basic/lab03/PatternMatchingExercise.scala index 2544dcd9..9d5ac94d 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab03/PatternMatchingExercise.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab03/PatternMatchingExercise.scala @@ -44,15 +44,15 @@ object PatternMatchingExercise { *************************************************************************/ val pf1: PartialFunction[String, String] = { - error("fix me") + case _ => error("fix me") } val pf2: PartialFunction[String, String] = { - error("fix me") + case _ => error("fix me") } val pf3:PartialFunction[String, String] = { - error("fix me") + case _ => error("fix me") } } From 18ca05e2d952d1ea4950be65262ff24f387be36c Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Wed, 27 May 2015 09:13:19 +0200 Subject: [PATCH 15/81] Add scalariform to maven pom.xml --- labs/pom.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/labs/pom.xml b/labs/pom.xml index 95064e50..74a47ef4 100644 --- a/labs/pom.xml +++ b/labs/pom.xml @@ -254,6 +254,22 @@ + + org.scalariform + scalariform-maven-plugin + + + process-sources + + format + + + true + + + + + From 12f814a91e74fd290ab861bdd5905ac932545c1e Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Wed, 27 May 2015 09:51:44 +0200 Subject: [PATCH 16/81] Add scalariform configuration to sbt --- labs/build.sbt | 2 ++ labs/project/plugins.sbt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/labs/build.sbt b/labs/build.sbt index b4f85b7e..69e07940 100644 --- a/labs/build.sbt +++ b/labs/build.sbt @@ -30,3 +30,5 @@ libraryDependencies ++= Seq("joda-time" % "joda-time" % "1.6", "org.hibernate" % "hibernate-entitymanager" % "3.4.0.GA", "org.slf4j" % "slf4j-simple" % "1.4.2") +scalariformSettings + diff --git a/labs/project/plugins.sbt b/labs/project/plugins.sbt index c73030cd..9afa8974 100644 --- a/labs/project/plugins.sbt +++ b/labs/project/plugins.sbt @@ -4,3 +4,5 @@ addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5.2") addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0") + +addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0") From 0dbfcb85e196c060c5f8e942a0471e69442b2671 Mon Sep 17 00:00:00 2001 From: upeter Date: Thu, 18 Jun 2015 18:08:31 +0200 Subject: [PATCH 17/81] Simplified Euro DSL --- .../basic/lab04/ImplicitConversionExercise02.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala index 54127523..d6f76008 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab04/ImplicitConversionExercise02.scala @@ -46,14 +46,14 @@ object ImplicitConversionExercises02 { */ object Exercise01 { - class EuroBuilder(val amount: Int, val inCents: Int) { - def euros = new EuroBuilder(0, inCents + amount * 100) - def cents = new EuroBuilder(0, inCents + amount) - def apply(amount: Int) = new EuroBuilder(amount, inCents) + class EuroBuilder(val inCents: Int) { + def euros = new EuroBuilder(inCents * 100) + def cents = Euro.fromCents(inCents) + def apply(cents: Int) = new EuroBuilder(inCents + cents) } - implicit def fromEuroBuilder(eb: EuroBuilder): Euro = Euro.fromCents(eb.inCents) - implicit def fromInt(value: Int): EuroBuilder = new EuroBuilder(value, 0) + implicit def fromIntToEuroBuilder(value: Int) = new EuroBuilder(value) + implicit def fromEuroBuilderToEuro(b: EuroBuilder) = Euro.fromCents(b.inCents) } /** From 428474471bda58c20cc0d958d9270bcd96e3332d Mon Sep 17 00:00:00 2001 From: upeter Date: Thu, 18 Jun 2015 18:10:16 +0200 Subject: [PATCH 18/81] minor improvement for case class match --- .../org/scalalabs/basic/lab03/PatternMatchingExercise.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab03/PatternMatchingExercise.scala b/solutions/src/main/scala/org/scalalabs/basic/lab03/PatternMatchingExercise.scala index 7568f009..0981d7a9 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab03/PatternMatchingExercise.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab03/PatternMatchingExercise.scala @@ -37,7 +37,7 @@ object PatternMatchingExercise { def matchOnInputType(in: Any) = in match { case s: String => s"A string with length ${s.length}" case i: Int if i > 0 => "A positive integer" - case p @ Person(_,_) => s"A person with name: ${p.name}" + case Person(name,_) => s"A person with name: $name" case s: Seq[_] if (s.size > 10) => "Seq with more than 10 elements" case first :: second :: tail => s"first: $first, second: $second, rest: $tail" case o: Option[_] => "A Scala Option subtype" From ab042d6ad2c25fb09810e764a97c53dc5d9d8525 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Fri, 19 Jun 2015 02:25:47 +0200 Subject: [PATCH 19/81] Add scapegoat scala compiler plugin --- labs/pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/labs/pom.xml b/labs/pom.xml index 95064e50..43d29fb2 100644 --- a/labs/pom.xml +++ b/labs/pom.xml @@ -221,8 +221,16 @@ -unchecked -deprecation + -P:scapegoat:dataDir:target/scapegoat ${scala.version} + + + com.sksamuel.scapegoat + scalac-scapegoat-plugin_2.11 + 0.3.0 + + From 515372f93a8d092326436c987b117c40fa686fb7 Mon Sep 17 00:00:00 2001 From: upeter Date: Fri, 19 Jun 2015 11:57:56 +0200 Subject: [PATCH 20/81] Tests for ScalaTest and Specs2 --- .../scala/org/scalalabs/basic/lab01/OOExercise.scala | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala b/solutions/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala index 294c3ad9..a5318c98 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala @@ -6,9 +6,14 @@ abstract class Currency(val symbol: String) class Euro(val euro: Int, val cents: Int = 0) extends Currency("EUR") with Ordered[Euro] { lazy val inCents: Int = euro * 100 + cents - def +(other: Euro) = Euro.fromCents(inCents + other.inCents) + def +(other: Euro):Euro = Euro.fromCents(inCents + other.inCents) - def *(n: Int) = Euro.fromCents(n * inCents) + def *(n: Int):Euro = Euro.fromCents(n * inCents) + + def /(n:Int):Euro = { + if(n <= 0) throw new IllegalArgumentException("Divider must be greater than 0") + Euro.fromCents(inCents / n) + } override lazy val toString = s"$symbol: $euro,${if (cents > 0) f"$cents%02d" else "--"}" From 2e2ec84771e3e7abfede1b5c857d6945f969c231 Mon Sep 17 00:00:00 2001 From: upeter Date: Fri, 19 Jun 2015 12:00:32 +0200 Subject: [PATCH 21/81] ScalaTest and Specs2 tests --- .../basic/lab02/ImperativeSample.java | 2 +- .../basic/lab01/ScalaTestExerciseTest.scala | 22 ++++++++++++ .../basic/lab01/Specs2ExerciseTest.scala | 21 +++++++++++ .../basic/lab02/ImperativeSample.java | 25 +++++++++++++ .../basic/lab02/CollectionExercise.scala | 8 +++++ .../basic/lab01/ScalaTestExerciseTest.scala | 35 ++++++++++++++++++ .../basic/lab01/Specs2ExerciseTest.scala | 36 +++++++++++++++++++ 7 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 labs/src/test/scala/org/scalalabs/basic/lab01/ScalaTestExerciseTest.scala create mode 100644 labs/src/test/scala/org/scalalabs/basic/lab01/Specs2ExerciseTest.scala create mode 100644 solutions/src/test/scala/org/scalalabs/basic/lab01/ScalaTestExerciseTest.scala create mode 100644 solutions/src/test/scala/org/scalalabs/basic/lab01/Specs2ExerciseTest.scala diff --git a/labs/src/main/java/org/scalalabs/basic/lab02/ImperativeSample.java b/labs/src/main/java/org/scalalabs/basic/lab02/ImperativeSample.java index d71d1444..f7de3992 100644 --- a/labs/src/main/java/org/scalalabs/basic/lab02/ImperativeSample.java +++ b/labs/src/main/java/org/scalalabs/basic/lab02/ImperativeSample.java @@ -1,5 +1,5 @@ package org.scalalabs.basic.lab02; - + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/labs/src/test/scala/org/scalalabs/basic/lab01/ScalaTestExerciseTest.scala b/labs/src/test/scala/org/scalalabs/basic/lab01/ScalaTestExerciseTest.scala new file mode 100644 index 00000000..da2024d8 --- /dev/null +++ b/labs/src/test/scala/org/scalalabs/basic/lab01/ScalaTestExerciseTest.scala @@ -0,0 +1,22 @@ +package org.scalalabs.basic.lab01 + +import org.junit.runner.RunWith +import org.scalatest._ +import org.scalatest.junit._ +/** + * In this Lab you will implement a ScalaTest testcase. + * + * Instructions: + * 1. Implement the divide method in Euro that has the following signature: def /(divider:Int) = ??? + * - If the divider is <=0 throw an IllegalArgumentException + * + * 2. Write a ScalaTest using a Spec of your choice to test: + * - Happy flow (divider is > 0) + * - Alternative flow (divider is <= 0) + */ +@RunWith(classOf[JUnitRunner]) +class ScalaTestExerciseTest { + + + +} diff --git a/labs/src/test/scala/org/scalalabs/basic/lab01/Specs2ExerciseTest.scala b/labs/src/test/scala/org/scalalabs/basic/lab01/Specs2ExerciseTest.scala new file mode 100644 index 00000000..625854f7 --- /dev/null +++ b/labs/src/test/scala/org/scalalabs/basic/lab01/Specs2ExerciseTest.scala @@ -0,0 +1,21 @@ +package org.scalalabs.basic.lab01 + +import org.junit.runner.RunWith +import org.specs2.runner.JUnitRunner +/** + * In this Lab you will implement a Specs2 testcase. + * + * Instructions: + * 1. Implement the divide method in Euro that has the following signature: def /(divider:Int) = ??? + * - If the divider is <=0 throw an IllegalArgumentException + * + * 2. Write a Specs2 specification to test: + * - Happy flow (divider is > 0) + * - Alternative flow (divider is <= 0) + */ +@RunWith(classOf[JUnitRunner]) +class Specs2ExerciseTest { + + + +} diff --git a/solutions/src/main/java/org/scalalabs/basic/lab02/ImperativeSample.java b/solutions/src/main/java/org/scalalabs/basic/lab02/ImperativeSample.java index d71d1444..3bc89653 100644 --- a/solutions/src/main/java/org/scalalabs/basic/lab02/ImperativeSample.java +++ b/solutions/src/main/java/org/scalalabs/basic/lab02/ImperativeSample.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +//import java.util.stream.Collectors; /** * This piece of java code depicts an imperative approach @@ -74,6 +75,27 @@ public int compare(Person p1, Person p2) { return adultsPerAgeGroup; } + /* + * Java 8 counterparts with lambda's + */ + /* + public static Map> groupAdultsPerAgeGroupLambda(List persons) { + return persons.stream().filter(p -> p.getAge() >= 18) + .sorted(Comparator.comparing(Person::getName)) + .collect(Collectors.groupingBy(p -> p.getAge() / 10 * 10)); + } + + public static Map groupAdultsCountsPerAgeGroupLambda(List persons) { + return persons.stream() + .filter(p -> p.getAge() >= 18) + .sorted(Comparator.comparing(Person::getName)) + .collect(Collectors.groupingBy(p -> p.getAge() / 10 * 10)) + .entrySet() + .stream() + .collect(Collectors.toMap(k -> k.getKey(), p -> p.getValue().size())); + } +*/ + public static void main(String[] args) { Map> adultsPerAgeGroup = groupAdultsPerAgeGroup(persons); assert(expected.equals(adultsPerAgeGroup)); @@ -104,3 +126,6 @@ public String toString() { } } + + + diff --git a/solutions/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala b/solutions/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala index 24058698..0367f938 100644 --- a/solutions/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala +++ b/solutions/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala @@ -80,6 +80,14 @@ object CollectionExercise02 { .sortBy(_.name) .groupBy(_.age / 10 * 10) } + + def groupAdultsCountPerAgeGroup(persons: Seq[Person]): Map[Int, Int] = { + persons.filter(_.age >= 18) + .sortBy(_.name) + .groupBy(_.age / 10 * 10) + .map{case (ageGroup, persons) => ageGroup -> persons.size} + } + } /*========================================================== */ diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab01/ScalaTestExerciseTest.scala b/solutions/src/test/scala/org/scalalabs/basic/lab01/ScalaTestExerciseTest.scala new file mode 100644 index 00000000..8befc66b --- /dev/null +++ b/solutions/src/test/scala/org/scalalabs/basic/lab01/ScalaTestExerciseTest.scala @@ -0,0 +1,35 @@ +package org.scalalabs.basic.lab01 + +import org.junit.runner.RunWith +import org.scalatest._ +import org.scalatest.junit._ +/** + * In this Lab you will implement a ScalaTest testcase. + * + * Instructions: + * 1. Implement the divide method in Euro that has the following signature: def /(divider:Int) = ??? + * - If the divider is <=0 throw an IllegalArgumentException + * + * 2. Write a ScalaTest using a Spec of your choice to test: + * - Happy flow (divider is > 0) + * - Alternative flow (divider is <= 0) + */ +@RunWith(classOf[JUnitRunner]) +class ScalaTestExerciseTest extends FunSpecLike with Matchers { + + var state = 0 + describe("Euro") { + it("should be divisible") { + val input = new Euro(1,20) + val result = input / 5 + result.euro should be(0) + result.cents should be(24) + } + + it("must produce an IllegalArgumentException if divided with <= 0") { + intercept[IllegalArgumentException]{new Euro(1,2) / 0} + } + + } + +} diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab01/Specs2ExerciseTest.scala b/solutions/src/test/scala/org/scalalabs/basic/lab01/Specs2ExerciseTest.scala new file mode 100644 index 00000000..31ca4ba9 --- /dev/null +++ b/solutions/src/test/scala/org/scalalabs/basic/lab01/Specs2ExerciseTest.scala @@ -0,0 +1,36 @@ +package org.scalalabs.basic.lab01 + + +import java.lang.{ IllegalArgumentException => IAE } +import org.junit.runner.RunWith +import org.specs2.mutable.Specification +import org.specs2.runner.JUnitRunner +/** + * In this Lab you will implement a Specs2 testcase. + * + * Instructions: + * 1. Implement the divide method in Euro that has the following signature: def /(divider:Int) = ??? + * - If the divider is <=0 throw an IllegalArgumentException + * + * 2. Write a Specs2 specification to test: + * - Happy flow (divider is > 0) + * - Alternative flow (divider is <= 0) + */ +@RunWith(classOf[JUnitRunner]) +class Specs2ExerciseTest extends Specification { + + "Euro" should { + "be divisible" in { + val input = new Euro(1,20) + val result = input / 5 + result.euro ==== 0 + result.cents ==== 24 + } + + "produce an IllegalArgumentException if divided with <= 0" in { + new Euro(1,2) / 0 must throwAn[IllegalArgumentException] + } + + } + +} From fadc0c6cc230bcbcdb456001e99b7109ebba564d Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Fri, 19 Jun 2015 12:27:22 +0200 Subject: [PATCH 22/81] Add scapegoat plugin No other configuration was necessary --- labs/project/plugins.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/labs/project/plugins.sbt b/labs/project/plugins.sbt index 9afa8974..3155864c 100644 --- a/labs/project/plugins.sbt +++ b/labs/project/plugins.sbt @@ -6,3 +6,5 @@ addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5.2") addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0") addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0") + +addSbtPlugin("com.sksamuel.scapegoat" %% "sbt-scapegoat" % "1.0.0") From ae20b391d2bde81e6b40bb2b7c3bfb96e08a66c0 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Fri, 19 Jun 2015 12:30:41 +0200 Subject: [PATCH 23/81] Add scoverage sbt plugin no further configuration necessary, 'sbt clean coverage test' works --- labs/project/plugins.sbt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/labs/project/plugins.sbt b/labs/project/plugins.sbt index 9afa8974..2717a550 100644 --- a/labs/project/plugins.sbt +++ b/labs/project/plugins.sbt @@ -6,3 +6,6 @@ addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5.2") addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0") addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0") + +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.1.0") + From fe17687ac32a00cfea371ca4b52f988f6f1d0e7e Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Fri, 19 Jun 2015 12:57:02 +0200 Subject: [PATCH 24/81] Add scoverage plugin Unfortunately it seems no reports are generated when the tests fail --- labs/pom.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/labs/pom.xml b/labs/pom.xml index 34daa592..cab0caf7 100644 --- a/labs/pom.xml +++ b/labs/pom.xml @@ -277,7 +277,14 @@ - + + org.scoverage + scoverage-maven-plugin + 1.1.0 + + 2.11.6 + + From 6ce405ef7868b118fc72e52aa614cbcb9dd4e7ad Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Fri, 19 Jun 2015 13:10:42 +0200 Subject: [PATCH 25/81] Add scoverage plugin to solutions pom, too --- solutions/pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solutions/pom.xml b/solutions/pom.xml index 40e0b7e7..0f2f8e6a 100644 --- a/solutions/pom.xml +++ b/solutions/pom.xml @@ -253,6 +253,14 @@ + + org.scoverage + scoverage-maven-plugin + 1.1.0 + + ${scala.version} + + From f302d227ecc39befa7774ed2461be0c080001d9d Mon Sep 17 00:00:00 2001 From: upeter Date: Fri, 19 Jun 2015 13:40:46 +0200 Subject: [PATCH 26/81] scalariform in solutions --- solutions/build.sbt | 1 + solutions/pom.xml | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/solutions/build.sbt b/solutions/build.sbt index 8a1d08cd..f6b6ef0d 100644 --- a/solutions/build.sbt +++ b/solutions/build.sbt @@ -32,3 +32,4 @@ libraryDependencies ++= Seq("joda-time" % "joda-time" % "1.6", "org.hibernate" % "hibernate-entitymanager" % "3.4.0.GA", "org.slf4j" % "slf4j-simple" % "1.4.2") +scalariformSettings diff --git a/solutions/pom.xml b/solutions/pom.xml index 40e0b7e7..4357a117 100644 --- a/solutions/pom.xml +++ b/solutions/pom.xml @@ -253,6 +253,21 @@ + + org.scalariform + scalariform-maven-plugin + + + process-sources + + format + + + true + + + + From f68e6923a733c35ed4d62b4b45c6cbc96ecddeb0 Mon Sep 17 00:00:00 2001 From: upeter Date: Fri, 19 Jun 2015 16:53:34 +0200 Subject: [PATCH 27/81] Improved test for function exercise --- .../org/scalalabs/basic/lab03/FunctionsExerciseTest.scala | 4 ++-- .../org/scalalabs/basic/lab03/FunctionsExerciseTest.scala | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/labs/src/test/scala/org/scalalabs/basic/lab03/FunctionsExerciseTest.scala b/labs/src/test/scala/org/scalalabs/basic/lab03/FunctionsExerciseTest.scala index 6ab7bde3..5f83cfdf 100644 --- a/labs/src/test/scala/org/scalalabs/basic/lab03/FunctionsExerciseTest.scala +++ b/labs/src/test/scala/org/scalalabs/basic/lab03/FunctionsExerciseTest.scala @@ -13,12 +13,12 @@ class FunctionsExerciseTest extends Specification { "FunctionsExercise01" should { "measure execution time" in { def block: Int = { - Thread.sleep(3) + Thread.sleep(10) 4 } //uncomment next line //4 ==== FunctionsExercise01.measure(block) - FunctionsExercise01.printed startsWith ("The execution took: ") + FunctionsExercise01.printed must beMatching ("""The execution took: ([1-9][0-9]) ms""") } } "FunctionsExercise02" should { diff --git a/solutions/src/test/scala/org/scalalabs/basic/lab03/FunctionsExerciseTest.scala b/solutions/src/test/scala/org/scalalabs/basic/lab03/FunctionsExerciseTest.scala index 878d8398..1f9fbb63 100644 --- a/solutions/src/test/scala/org/scalalabs/basic/lab03/FunctionsExerciseTest.scala +++ b/solutions/src/test/scala/org/scalalabs/basic/lab03/FunctionsExerciseTest.scala @@ -13,11 +13,11 @@ class FunctionsExerciseTest extends Specification { "FunctionsExercise01" should { "measure execution time" in { def block = { - Thread.sleep(3) + Thread.sleep(10) 4 } 4 ==== FunctionsExercise01.measure(block) - FunctionsExercise01.printed startsWith ("The execution took: ") + FunctionsExercise01.printed must beMatching ("""The execution took: ([1-9][0-9]) ms""") } } "FunctionsExercise2" should { From fb2ad9489a41e1a4daacab7f520fdd38fb99f316 Mon Sep 17 00:00:00 2001 From: upeter Date: Fri, 19 Jun 2015 16:54:35 +0200 Subject: [PATCH 28/81] Formatted sources with scalariform --- ...Maven__commons_codec_commons_codec_1_2.xml | 13 -- ...mons_httpclient_commons_httpclient_3_1.xml | 13 -- ..._commons_logging_commons_logging_1_0_4.xml | 13 -- .../Maven__joda_time_joda_time_1_6.xml | 13 -- .../libraries/Maven__junit_junit_4_7.xml | 13 -- ...en__org_scala_lang_scala_library_2_7_5.xml | 13 -- .../Maven__org_scalatest_scalatest_1_0.xml | 13 -- .../advanced/lab01/ActorExercise.scala | 10 +- .../lab01/PatternMatchingExercise.scala | 55 +++--- .../lab02/ControlStructureExercise.scala | 6 +- .../lab02/ParserCombinatorExercise.scala | 20 +-- .../advanced/lab03/ChurchEncoding.scala | 41 +++-- .../advanced/lab03/ImplicitExercise.scala | 79 ++++----- .../scalalabs/advanced/lab03/TSRegistry.scala | 2 +- .../advanced/lab03/TypeExercise.scala | 33 ++-- .../scalalabs/advanced/lab04/Director.scala | 28 +-- .../advanced/lab04/GenericRepository.scala | 12 +- .../advanced/lab04/JpaExercise.scala | 45 +++-- .../org/scalalabs/advanced/lab04/Movie.scala | 19 +- .../scalalabs/advanced/lab04/Repository.scala | 6 +- .../basic/lab01/CurrencyConverter.scala | 5 +- .../basic/lab01/HelloWorldExercise.scala | 40 ++--- .../scalalabs/basic/lab01/OOExercise.scala | 18 +- .../basic/lab02/CollectionExercise.scala | 3 - .../lab02/ListManipulationExercise01.scala | 15 +- .../lab02/ListManipulationExercise02.scala | 13 +- .../basic/lab03/ForExpressionExercise.scala | 6 +- .../basic/lab03/FunctionsExercise.scala | 4 +- .../basic/lab03/PatternMatchingExercise.scala | 14 +- .../RecursionPatternMatchingExercise.scala | 6 +- .../lab04/ImplicitConversionExercise02.scala | 43 +++-- .../scalalabs/basic/lab04/TraitExercise.scala | 24 ++- .../intermediate/lab01/TwitterUser.scala | 1 - .../intermediate/lab02/TwitterStatus.scala | 67 ++++--- .../intermediate/lab02/TwitterUser.scala | 47 +++-- .../intermediate/lab02/TwitterUsers.scala | 3 +- .../intermediate/lab03/TwitterSession.scala | 82 ++++----- .../intermediate/lab03/TwitterStatus.scala | 85 +++++---- .../intermediate/lab03/TwitterTimeline.scala | 1 - .../intermediate/lab03/TwitterUser.scala | 66 ++++--- .../intermediate/lab04/PaymentService.scala | 10 +- .../advanced/lab01/ActorExerciseTest.scala | 48 +++-- .../lab01/PatternMatchingExerciseTest.scala | 30 ++-- .../lab02/ControlStructureExerciseTest.scala | 8 +- .../lab02/ParserCombinatorExerciseTest.scala | 3 +- .../advanced/lab03/ImplicitExerciseTest.scala | 93 +++++----- .../advanced/lab03/TypeExerciseTest.scala | 61 +++---- .../advanced/lab04/JpaExerciseTest.scala | 21 +-- .../basic/lab01/OOExerciseTest.scala | 34 ++-- .../basic/lab01/ScalaTestExerciseTest.scala | 8 +- .../basic/lab01/Specs2ExerciseTest.scala | 8 +- .../basic/lab02/CollectionExerciseTest.scala | 4 +- .../ListManipulationExercise01Test.scala | 10 +- .../ListManipulationExercise02Test.scala | 66 +++---- .../lab03/ForExpressionExerciseTest.scala | 2 +- .../lab03/PatternMatchingExerciseTest.scala | 2 +- ...RecursionPatternMatchingExerciseTest.scala | 4 +- .../ImplicitConversionExercise01Test.scala | 46 ++--- .../ImplicitConversionExercise02Test.scala | 1 - .../basic/lab04/TraitExerciseTest.scala | 10 +- .../lab01/FirstExerciseTest.scala | 114 ++++++------ .../lab02/SecondExerciseBonusTest.scala | 120 +++++++------ .../lab02/SecondExerciseTest.scala | 130 +++++++------- .../lab03/ThirdExerciseTest.scala | 139 ++++++++------- .../lab04/PaymentClientTest.scala | 8 +- .../advanced/lab01/ActorExercise.scala | 26 ++- .../lab01/PatternMatchingExercise.scala | 90 +++++----- .../lab02/ControlStructureExercise.scala | 6 +- .../lab02/ParserCombinatorExercise.scala | 24 +-- .../advanced/lab03/ChurchEncoding.scala | 49 +++--- .../advanced/lab03/ImplicitExercise.scala | 107 +++++------- .../advanced/lab03/TypeExercise.scala | 74 ++++---- .../org/scalalabs/advanced/lab03/Units.scala | 6 +- .../scalalabs/advanced/lab04/Director.scala | 30 ++-- .../advanced/lab04/GenericRepository.scala | 34 ++-- .../advanced/lab04/JpaExercise.scala | 49 +++--- .../org/scalalabs/advanced/lab04/Movie.scala | 17 +- .../scalalabs/advanced/lab04/Repository.scala | 7 +- .../basic/lab01/CurrencyConverter.scala | 5 +- .../basic/lab01/HelloWorldExercise.scala | 36 ++-- .../scalalabs/basic/lab01/OOExercise.scala | 14 +- .../basic/lab02/CollectionExercise.scala | 9 +- .../lab02/ListManipulationExercise01.scala | 14 +- .../lab02/ListManipulationExercise02.scala | 13 +- .../basic/lab03/ForExpressionExercise.scala | 20 +-- .../basic/lab03/FunctionsExercise.scala | 1 - .../basic/lab03/OptionExercise.scala | 23 +-- .../basic/lab03/PatternMatchingExercise.scala | 2 +- .../RecursionPatternMatchingExercise.scala | 4 +- .../scalalabs/basic/lab04/TraitExercise.scala | 6 +- .../intermediate/lab01/TwitterStatus.scala | 61 ++++--- .../intermediate/lab01/TwitterUser.scala | 46 ++--- .../intermediate/lab02/TwitterStatus.scala | 91 +++++----- .../intermediate/lab02/TwitterUser.scala | 84 +++++---- .../intermediate/lab02/TwitterUsers.scala | 56 +++--- .../intermediate/lab03/TwitterSession.scala | 164 +++++++++--------- .../intermediate/lab03/TwitterStatus.scala | 85 +++++---- .../intermediate/lab03/TwitterTimeline.scala | 3 +- .../intermediate/lab03/TwitterUser.scala | 66 ++++--- .../intermediate/lab03/TwitterUsers.scala | 3 +- .../intermediate/lab04/PaymentService.scala | 10 +- .../advanced/lab01/ActorExerciseTest.scala | 52 +++--- .../lab01/PatternMatchingExerciseTest.scala | 31 ++-- .../lab02/ControlStructureExerciseTest.scala | 4 +- .../lab02/ParserCombinatorExerciseTest.scala | 3 +- .../advanced/lab03/ImplicitExerciseTest.scala | 14 +- .../advanced/lab03/TypeExerciseTest.scala | 5 +- .../advanced/lab04/JpaExerciseTest.scala | 20 +-- .../basic/lab01/ScalaTestExerciseTest.scala | 14 +- .../basic/lab01/Specs2ExerciseTest.scala | 15 +- .../basic/lab02/CollectionExerciseTest.scala | 2 +- .../ListManipulationExercise01Test.scala | 10 +- .../ListManipulationExercise02Test.scala | 62 +++---- .../lab03/PatternMatchingExerciseTest.scala | 2 +- .../ImplicitConversionExercise01Test.scala | 2 +- .../ImplicitConversionExercise02Test.scala | 2 +- .../basic/lab04/TraitExerciseTest.scala | 4 +- .../lab01/FirstExerciseTest.scala | 93 +++++----- .../lab02/SecondExerciseBonusTest.scala | 112 ++++++------ .../lab02/SecondExerciseTest.scala | 111 ++++++------ .../lab04/PaymentClientTest.scala | 26 +-- 121 files changed, 1819 insertions(+), 2070 deletions(-) delete mode 100644 labs/.idea/libraries/Maven__commons_codec_commons_codec_1_2.xml delete mode 100644 labs/.idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml delete mode 100644 labs/.idea/libraries/Maven__commons_logging_commons_logging_1_0_4.xml delete mode 100644 labs/.idea/libraries/Maven__joda_time_joda_time_1_6.xml delete mode 100644 labs/.idea/libraries/Maven__junit_junit_4_7.xml delete mode 100644 labs/.idea/libraries/Maven__org_scala_lang_scala_library_2_7_5.xml delete mode 100644 labs/.idea/libraries/Maven__org_scalatest_scalatest_1_0.xml diff --git a/labs/.idea/libraries/Maven__commons_codec_commons_codec_1_2.xml b/labs/.idea/libraries/Maven__commons_codec_commons_codec_1_2.xml deleted file mode 100644 index fbcb9929..00000000 --- a/labs/.idea/libraries/Maven__commons_codec_commons_codec_1_2.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/.idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml b/labs/.idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml deleted file mode 100644 index 66e65371..00000000 --- a/labs/.idea/libraries/Maven__commons_httpclient_commons_httpclient_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/.idea/libraries/Maven__commons_logging_commons_logging_1_0_4.xml b/labs/.idea/libraries/Maven__commons_logging_commons_logging_1_0_4.xml deleted file mode 100644 index 217d6e0a..00000000 --- a/labs/.idea/libraries/Maven__commons_logging_commons_logging_1_0_4.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/.idea/libraries/Maven__joda_time_joda_time_1_6.xml b/labs/.idea/libraries/Maven__joda_time_joda_time_1_6.xml deleted file mode 100644 index a6fe1789..00000000 --- a/labs/.idea/libraries/Maven__joda_time_joda_time_1_6.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/.idea/libraries/Maven__junit_junit_4_7.xml b/labs/.idea/libraries/Maven__junit_junit_4_7.xml deleted file mode 100644 index 4402995f..00000000 --- a/labs/.idea/libraries/Maven__junit_junit_4_7.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/.idea/libraries/Maven__org_scala_lang_scala_library_2_7_5.xml b/labs/.idea/libraries/Maven__org_scala_lang_scala_library_2_7_5.xml deleted file mode 100644 index dacf0430..00000000 --- a/labs/.idea/libraries/Maven__org_scala_lang_scala_library_2_7_5.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/.idea/libraries/Maven__org_scalatest_scalatest_1_0.xml b/labs/.idea/libraries/Maven__org_scalatest_scalatest_1_0.xml deleted file mode 100644 index a3c24871..00000000 --- a/labs/.idea/libraries/Maven__org_scalatest_scalatest_1_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/labs/src/main/scala/org/scalalabs/advanced/lab01/ActorExercise.scala b/labs/src/main/scala/org/scalalabs/advanced/lab01/ActorExercise.scala index 70e7ebc5..62e224bc 100644 --- a/labs/src/main/scala/org/scalalabs/advanced/lab01/ActorExercise.scala +++ b/labs/src/main/scala/org/scalalabs/advanced/lab01/ActorExercise.scala @@ -7,7 +7,7 @@ package org.scalalabs.advanced.lab01 * Messages are processed asynchronously and Actor's process only one message at a time. * Because the actor's state can only be modified by sending a message, and messages are processed serially * they are thread-safe by default. - * It is therefore an interesting alternative to the normal concurrency model of taking locks. + * It is therefore an interesting alternative to the normal concurrency model of taking locks. */ import scala.actors.Actor @@ -29,7 +29,8 @@ case object Curr class Counter extends Actor { private var value: Int = 0 - /**implement the act method so that it: + /** + * implement the act method so that it: *