diff --git a/admin/app/commercial/TravelOffersCacheJob.scala b/admin/app/commercial/TravelOffersCacheJob.scala index aec56dec67d9..319096530323 100644 --- a/admin/app/commercial/TravelOffersCacheJob.scala +++ b/admin/app/commercial/TravelOffersCacheJob.scala @@ -29,7 +29,7 @@ object TravelOffersCacheJob extends ExecutionContexts with Dates with Logging { def run() { - future { + Future { url map {u => val start = System.currentTimeMillis diff --git a/admin/app/dfp/DataAgent.scala b/admin/app/dfp/DataAgent.scala index 286a5a45d160..2545c1db89de 100644 --- a/admin/app/dfp/DataAgent.scala +++ b/admin/app/dfp/DataAgent.scala @@ -3,10 +3,11 @@ package dfp import common.{AkkaAgent, ExecutionContexts, Logging} import conf.Switches._ +import org.apache.commons.lang.exception.ExceptionUtils import scala.concurrent.Future import scala.util.{Failure, Success, Try} -trait DataAgent[K, V] extends ExecutionContexts with Logging { +trait DataAgent[K, V] extends ExecutionContexts with Logging with implicits.Strings { private val initialCache: DataCache[K, V] = DataCache(Map.empty[K, V]) private lazy val cache = AkkaAgent(initialCache) @@ -29,7 +30,7 @@ trait DataAgent[K, V] extends ExecutionContexts with Logging { oldCache } case Failure(e) => - log.error(e.getStackTraceString) + log.error(ExceptionUtils.getStackTrace(e)) oldCache } } else { diff --git a/admin/app/dfp/DfpDataCacheJob.scala b/admin/app/dfp/DfpDataCacheJob.scala index df1705ae01d1..154c494c591e 100644 --- a/admin/app/dfp/DfpDataCacheJob.scala +++ b/admin/app/dfp/DfpDataCacheJob.scala @@ -6,11 +6,11 @@ import org.joda.time.DateTime import play.api.libs.json.Json.{toJson, _} import tools.Store -import scala.concurrent.{Future, future} +import scala.concurrent.Future object DfpDataCacheJob extends ExecutionContexts with Logging { - def run(): Future[Unit] = future { + def run(): Future[Unit] = Future { if (DfpCachingSwitch.isSwitchedOn) { log.info("Refreshing data cache") val start = System.currentTimeMillis diff --git a/admin/app/dfp/DfpDataHydrator.scala b/admin/app/dfp/DfpDataHydrator.scala index d69020f3b02e..f35fb73312f2 100644 --- a/admin/app/dfp/DfpDataHydrator.scala +++ b/admin/app/dfp/DfpDataHydrator.scala @@ -5,6 +5,7 @@ import com.google.api.ads.dfp.axis.v201411._ import common.Logging import conf.Configuration.commercial.guMerchandisingAdvertiserId import dfp.DfpApiWrapper.DfpSessionException +import org.apache.commons.lang.exception.ExceptionUtils import org.joda.time.{DateTimeZone, DateTime => JodaDateTime} import scala.util.{Failure, Try} @@ -108,7 +109,7 @@ class DfpDataHydrator extends Logging { } catch { case e: Exception => - log.error(e.getStackTraceString) + log.error(ExceptionUtils.getStackTrace(e)) Nil } } diff --git a/admin/app/jobs/OmnitureReportJob.scala b/admin/app/jobs/OmnitureReportJob.scala index e3484af370c5..7ce4098dcd51 100644 --- a/admin/app/jobs/OmnitureReportJob.scala +++ b/admin/app/jobs/OmnitureReportJob.scala @@ -5,7 +5,7 @@ import org.joda.time.{DateTimeZone, DateTime} import services.Omniture._ import OmnitureMethods._ import scala.concurrent.duration._ -import scala.concurrent.future +import scala.concurrent.Future object OmnitureVariables { // Metrics @@ -50,7 +50,7 @@ object OmnitureReportJob extends ExecutionContexts with Logging { val dateFrom = dateTo.minusWeeks(2) // Stagger each report request, otherwise omniture request nonce values will be identical. - akka.pattern.after(1.seconds, actorSystem.scheduler) (future { + akka.pattern.after(1.seconds, actorSystem.scheduler) (Future { generateReport(OmnitureReportDescription( dateGranularity = Some("day"), dateTo = dateTo.toString("yyyy-MM-dd"), @@ -60,7 +60,7 @@ object OmnitureReportJob extends ExecutionContexts with Logging { ), QUEUE_OVERTIME, galleryPageViews) }) - akka.pattern.after(5.seconds, actorSystem.scheduler) (future { + akka.pattern.after(5.seconds, actorSystem.scheduler) (Future { generateReport(OmnitureReportDescription( dateGranularity = Some("day"), dateTo = dateTo.toString("yyyy-MM-dd"), @@ -70,7 +70,7 @@ object OmnitureReportJob extends ExecutionContexts with Logging { ), QUEUE_OVERTIME, galleryVisits) }) - akka.pattern.after(10.seconds, actorSystem.scheduler) (future { + akka.pattern.after(10.seconds, actorSystem.scheduler) (Future { generateReport(OmnitureReportDescription( dateGranularity = Some("day"), dateTo = dateTo.toString("yyyy-MM-dd"), @@ -80,7 +80,7 @@ object OmnitureReportJob extends ExecutionContexts with Logging { ), QUEUE_OVERTIME, galleryLightBox) }) - akka.pattern.after(15.seconds, actorSystem.scheduler) ( future { + akka.pattern.after(15.seconds, actorSystem.scheduler) (Future { generateReport(OmnitureReportDescription( dateGranularity = Some("day"), dateTo = dateTo.toString("yyyy-MM-dd"), @@ -90,7 +90,7 @@ object OmnitureReportJob extends ExecutionContexts with Logging { ), QUEUE_OVERTIME, gallerySocialShare) }) - akka.pattern.after(20.seconds, actorSystem.scheduler) ( future { + akka.pattern.after(20.seconds, actorSystem.scheduler) (Future { generateReport(OmnitureReportDescription( dateGranularity = Some("day"), dateTo = dateTo.toString("yyyy-MM-dd"), @@ -101,7 +101,7 @@ object OmnitureReportJob extends ExecutionContexts with Logging { ), QUEUE_OVERTIME, googleReferrerVisits) }) - akka.pattern.after(25.seconds, actorSystem.scheduler) ( future { + akka.pattern.after(25.seconds, actorSystem.scheduler) (Future { generateReport(OmnitureReportDescription( dateGranularity = Some("day"), dateTo = dateTo.toString("yyyy-MM-dd"), @@ -111,7 +111,7 @@ object OmnitureReportJob extends ExecutionContexts with Logging { ), QUEUE_OVERTIME, networkTotalVisits) }) - akka.pattern.after(30.seconds, actorSystem.scheduler) ( future { + akka.pattern.after(30.seconds, actorSystem.scheduler) (Future { generateReport(OmnitureReportDescription( dateGranularity = Some("day"), dateTo = dateTo.toString("yyyy-MM-dd"), diff --git a/common/app/common/JsonComponent.scala b/common/app/common/JsonComponent.scala index a05fe74d5e51..6309c2840317 100644 --- a/common/app/common/JsonComponent.scala +++ b/common/app/common/JsonComponent.scala @@ -10,8 +10,6 @@ import play.api.http.ContentTypes._ object JsonComponent extends Results with implicits.Requests { - type ListOfString = List[String] - private val ValidCallback = """([a-zA-Z0-9_]+)""".r def apply(html: Html)(implicit request: RequestHeader): Result = { @@ -54,7 +52,7 @@ object JsonComponent extends Results with implicits.Requests { case (name, value: Int) => name -> toJson(value) case (name, value: Double) => name -> toJson(value) case (name, value: Float) => name -> toJson(value) - case (name, value: ListOfString) => name -> toJson(value) + case (name, value: List[_]) if value.forall(_.isInstanceOf[String]) => name -> toJson(value.asInstanceOf[List[String]]) case (name, value: JsValue) => name -> value } )) diff --git a/common/app/implicits/Collections.scala b/common/app/implicits/Collections.scala index 0f9f224f7b93..5d61376909c1 100644 --- a/common/app/implicits/Collections.scala +++ b/common/app/implicits/Collections.scala @@ -22,4 +22,16 @@ trait Collections { builder.result } } + + // A non-inlined implementation of drop while. This is needed because scala 2.11 + // currently throws warnings (fatal warnings are on) when using standard drop while. + // https://issues.scala-lang.org/browse/SI-7529 + implicit class List2DropWhile[A](list: List[A]) { + def safeDropWhile(p: A => Boolean): List[A] = { + def loop(xs: List[A]): List[A] = + if (xs.isEmpty || !p(xs.head)) xs + else loop(xs.tail) + loop(list) + } + } } diff --git a/common/app/performance/MemcachedAction.scala b/common/app/performance/MemcachedAction.scala index 2b56447708db..2c478d98a445 100644 --- a/common/app/performance/MemcachedAction.scala +++ b/common/app/performance/MemcachedAction.scala @@ -30,7 +30,7 @@ private[performance] trait MemcachedSupport extends ExecutionContexts with impli lazy val isConfigured = Configuration.memcached.host.isDefined lazy val host = Configuration.memcached.host.head - lazy val memcached = Memcached(MemcachedConf(host), actorSystem.scheduler, memcachedExecutionContext) + lazy val memcached = Memcached(MemcachedConf(host), memcachedExecutionContext) implicit object ResultCodec extends Codec[CachedResponse] { diff --git a/common/app/performance/MemcachedFallback.scala b/common/app/performance/MemcachedFallback.scala index fa841c6cd01c..744c1a6334d6 100644 --- a/common/app/performance/MemcachedFallback.scala +++ b/common/app/performance/MemcachedFallback.scala @@ -28,7 +28,7 @@ object MemcacheTypeclass { object MemcachedFallback extends ExecutionContexts with Dates with Logging { private def connectToMemcached(host: String) = { val tryConnect = Try { - Memcached(MemcachedConf(host), actorSystem.scheduler, memcachedExecutionContext) + Memcached(MemcachedConf(host), memcachedExecutionContext) } tryConnect.failed foreach { error => diff --git a/common/app/services/S3.scala b/common/app/services/S3.scala index d4e38fc9cc1b..95d3b7730880 100644 --- a/common/app/services/S3.scala +++ b/common/app/services/S3.scala @@ -60,25 +60,20 @@ trait S3 extends Logging { } } - def get(key: String)(implicit codec: Codec): Option[String] = try { - withS3Result(key) { - result => Source.fromInputStream(result.getObjectContent).mkString - } + def get(key: String)(implicit codec: Codec): Option[String] = withS3Result(key) { + result => Source.fromInputStream(result.getObjectContent).mkString } - def getWithLastModified(key: String): Option[(String, DateTime)] = try { - withS3Result(key) { - result => - val content = Source.fromInputStream(result.getObjectContent).mkString - val lastModified = new DateTime(result.getObjectMetadata.getLastModified) - (content, lastModified) - } + + def getWithLastModified(key: String): Option[(String, DateTime)] = withS3Result(key) { + result => + val content = Source.fromInputStream(result.getObjectContent).mkString + val lastModified = new DateTime(result.getObjectMetadata.getLastModified) + (content, lastModified) } - def getLastModified(key: String): Option[DateTime] = try { - withS3Result(key) { - result => new DateTime(result.getObjectMetadata.getLastModified) - } + def getLastModified(key: String): Option[DateTime] = withS3Result(key) { + result => new DateTime(result.getObjectMetadata.getLastModified) } def putPublic(key: String, value: String, contentType: String) { diff --git a/common/app/views/support/package.scala b/common/app/views/support/package.scala index b11edbd76b72..442a17081dae 100644 --- a/common/app/views/support/package.scala +++ b/common/app/views/support/package.scala @@ -4,7 +4,6 @@ import common._ import model._ import org.apache.commons.lang.StringEscapeUtils -import org.jboss.dna.common.text.Inflector import org.joda.time.{LocalDate, DateTime} import org.joda.time.format.DateTimeFormat import org.jsoup.Jsoup @@ -82,8 +81,6 @@ object ContributorLinks { object `package` extends Formats { - private object inflector extends Inflector - def withJsoup(html: Html)(cleaners: HtmlCleaner*): Html = withJsoup(html.body) { cleaners: _* } def withJsoup(html: String)(cleaners: HtmlCleaner*): Html = { @@ -105,11 +102,6 @@ object `package` extends Formats { def typeOrTone: Option[Tag] = t.types.find(_.id != "type/article").orElse(t.tones.headOption) } - implicit class Tags2inflector(t: Tag) { - lazy val singularName: String = inflector.singularize(t.name) - lazy val pluralName: String = inflector.pluralize(t.name) - } - implicit class Seq2zipWithRowInfo[A](seq: Seq[A]) { def zipWithRowInfo = seq.zipWithIndex.map { case (item, index) => (item, RowInfo(index + 1, seq.length == index + 1)) diff --git a/common/test/common/ExternalLinksTest.scala b/common/test/common/ExternalLinksTest.scala index 9687b484896e..8392d99b2f58 100644 --- a/common/test/common/ExternalLinksTest.scala +++ b/common/test/common/ExternalLinksTest.scala @@ -49,7 +49,7 @@ class ExternalLinksTest extends FlatSpec with Matchers with Inspectors { it should "be false for malformed URLs" in { forAll(Seq( "htt://", - "\0" + "\u0000" )) { id => external(id) should be(false) } diff --git a/common/test/common/TrailsToRss.scala b/common/test/common/TrailsToRss.scala index a0b32cf66cc9..381f9aacd175 100644 --- a/common/test/common/TrailsToRss.scala +++ b/common/test/common/TrailsToRss.scala @@ -30,7 +30,7 @@ class TrailsToRssTest extends FlatSpec with Matchers { it should "strip invalid Unicode characters from XML" in { isWellFormedXML(TrailsToRss(Option("foo"), Seq( - TestTrail("h", customTitle = Some("\0LOL")) + TestTrail("h", customTitle = Some("\u0000LOL")) ))(request)) shouldBe true } diff --git a/common/test/views/support/TemplatesTest.scala b/common/test/views/support/TemplatesTest.scala index 44e2c8abac79..580ba5c8f272 100644 --- a/common/test/views/support/TemplatesTest.scala +++ b/common/test/views/support/TemplatesTest.scala @@ -47,15 +47,6 @@ class TemplatesTest extends FlatSpec with Matchers { tags.typeOrTone.get.id should be("tone/foo") } - "Inflector" should "singularize tag name" in { - Tag(tag("Minute by minutes")).singularName should be("Minute by minute") - Tag(tag("News")).singularName should be("News") - } - - it should "pluralize tag name" in { - Tag(tag("Article")).pluralName should be("Articles") - } - "PictureCleaner" should "correctly format inline pictures" in { val body = XML.loadString(withJsoup(bodyTextWithInlineElements)(PictureCleaner(testContent)).body.trim) diff --git a/discussion/test/discussion/DiscussionApiTest.scala b/discussion/test/discussion/DiscussionApiTest.scala index e3f16df2e427..34aa6ee5c162 100644 --- a/discussion/test/discussion/DiscussionApiTest.scala +++ b/discussion/test/discussion/DiscussionApiTest.scala @@ -16,7 +16,7 @@ import scala.language.postfixOps val discussionApi = new DiscussionApi { override protected def GET(url: String, headers: (String, String)*): Future[WSResponse] = { assert(expectedUrl === url) - future {null} // Don't care what is returned for this test + Future {null} // Don't care what is returned for this test } protected val clientHeaderValue: String = "" protected val apiRoot: String = "" @@ -39,7 +39,7 @@ import scala.language.postfixOps val discussionApi = new DiscussionApi { override protected def GET(url: String, headers: (String, String)*): Future[WSResponse] = { assert(expectedUrl === url) - future {null} + Future {null} } protected val clientHeaderValue: String = "" protected val apiRoot: String = "" diff --git a/identity/app/client/parser/JsonBodyParser.scala b/identity/app/client/parser/JsonBodyParser.scala index 61a2296a2258..baf471edcce0 100644 --- a/identity/app/client/parser/JsonBodyParser.scala +++ b/identity/app/client/parser/JsonBodyParser.scala @@ -27,7 +27,7 @@ trait JsonBodyParser extends Logging { case HttpResponse(body, status, message) if status > 299 => Left(extractErrorFromResponse(parse(body), httpResponse.statusCode)) case HttpResponse(body, status, message) if successType == manifest[Unit] => - Right().asInstanceOf[Right[List[client.Error], T]] + Right(()).asInstanceOf[Right[List[client.Error], T]] case HttpResponse(body, status, message) => Right(extractJsonObj(parse(body)).extract[T]) } diff --git a/identity/test/controllers/EmailVerificationControllerTest.scala b/identity/test/controllers/EmailVerificationControllerTest.scala index 844a30fabbb9..d09c0e31d0c4 100644 --- a/identity/test/controllers/EmailVerificationControllerTest.scala +++ b/identity/test/controllers/EmailVerificationControllerTest.scala @@ -36,7 +36,7 @@ class EmailVerificationControllerTest extends path.FreeSpec with ShouldMatchers val token = "myToken" "when the api call succeeds" - { - when(api.validateEmail(token, trackingData)).thenReturn(Future.successful(Right())) + when(api.validateEmail(token, trackingData)).thenReturn(Future.successful(Right(()))) val result = controller.verify(token)(testRequest) "should display the validation completed page" in { diff --git a/identity/test/controllers/ResetPasswordControllerTest.scala b/identity/test/controllers/ResetPasswordControllerTest.scala index 4c94ca842083..730e4700078f 100644 --- a/identity/test/controllers/ResetPasswordControllerTest.scala +++ b/identity/test/controllers/ResetPasswordControllerTest.scala @@ -46,7 +46,7 @@ class ResetPasswordControllerTest extends path.FreeSpec with ShouldMatchers with val fakeRequest = FakeRequest(POST, "/reset").withFormUrlEncodedBody("email-address" -> emailAddress) "with an api response validating the user" - { - when(api.sendPasswordResetEmail(any[String], any[TrackingData])).thenReturn(Future.successful(Right())) + when(api.sendPasswordResetEmail(any[String], any[TrackingData])).thenReturn(Future.successful(Right(()))) "should ask the api to send a reset email to the the the specified user" in Fake { resetPasswordController.processPasswordResetRequestForm(fakeRequest) @@ -107,7 +107,7 @@ class ResetPasswordControllerTest extends path.FreeSpec with ShouldMatchers with val fakeRequest = FakeRequest(POST, "/reset_password" ).withFormUrlEncodedBody("password" -> "newpassword", "password-confirm" -> "newpassword", "email-address" -> "test@somewhere.com") "when the token provided is valid" - { - when(api.resetPassword(Matchers.any[String], Matchers.any[String])).thenReturn(Future.successful(Right())) + when(api.resetPassword(Matchers.any[String], Matchers.any[String])).thenReturn(Future.successful(Right(()))) "should call the api the password with the provided new password and token" in Fake { resetPasswordController.resetPassword("1234")(fakeRequest) verify(api).resetPassword(Matchers.eq("1234"), Matchers.eq("newpassword")) diff --git a/png-resizer/app/controllers/Resizer.scala b/png-resizer/app/controllers/Resizer.scala index a704e363612b..49a67ccdba4b 100644 --- a/png-resizer/app/controllers/Resizer.scala +++ b/png-resizer/app/controllers/Resizer.scala @@ -64,7 +64,7 @@ object Resizer extends Controller with Logging with implicits.Requests { log.info(s"won't resize image to be bigger - $originalWidth to $width - redirecting to original") -\/(Cached(1.day)(Found(fallbackUri))) } else { - \/-() + \/-(()) } } diff --git a/png-resizer/app/load/LoadLimit.scala b/png-resizer/app/load/LoadLimit.scala index 2308a207232e..5978bf7678f9 100644 --- a/png-resizer/app/load/LoadLimit.scala +++ b/png-resizer/app/load/LoadLimit.scala @@ -16,7 +16,7 @@ object LoadLimit extends ExecutionContexts with Logging { limit } - def tryOperation[T](operation: => Future[T])(outOfCapacity: => Future[T]): Future[T] = try { + def tryOperation[T](operation: => Future[T])(outOfCapacity: => Future[T]): Future[T] = { val concurrentRequests = currentNumberOfRequests.incrementAndGet if (concurrentRequests <= requestLimit) try { log.info(s"Resize $concurrentRequests/$requestLimit") diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 5d0ab475888a..dc8a3f6da327 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,7 +4,7 @@ import sbt._ object Dependencies { val cucumberVersion = "1.1.5" - val identityLibVersion = "3.43" + val identityLibVersion = "3.44" val seleniumVersion = "2.44.0" val slf4jVersion = "1.7.5" @@ -15,14 +15,13 @@ object Dependencies { val commonsHttpClient = "commons-httpclient" % "commons-httpclient" % "3.1" val commonsIo = "commons-io" % "commons-io" % "2.4" val contentApiClient = "com.gu" %% "content-api-client" % "5.0" - val crosswordsApiClient = "com.gu" %% "crosswords-api-client" % "0.4" + val crosswordsApiClient = "com.gu" %% "crosswords-api-client" % "0.5" val dfpAxis = "com.google.api-ads" % "dfp-axis" % "1.35.1" - val dnaCommon = "org.jboss.dna" % "dna-common" % "0.6" - val exactTargetClient = "com.gu" %% "exact-target-client" % "2.23" + val exactTargetClient = "com.gu" %% "exact-target-client" % "2.24" val faciaScalaClient = "com.gu" %% "facia-json" % "0.15" - val flexibleContentBlockToText = "com.gu" %% "flexible-content-block-to-text" % "0.1" - val flexibleContentBodyParser = "com.gu" %% "flexible-content-body-parser" % "0.3" - val guardianConfiguration = "com.gu" %% "configuration" % "3.9" + val flexibleContentBlockToText = "com.gu" %% "flexible-content-block-to-text" % "0.4" + val flexibleContentBodyParser = "com.gu" %% "flexible-content-body-parser" % "0.6" + val guardianConfiguration = "com.gu" %% "configuration" % "4.0" val guice = "com.google.inject" % "guice" % "3.0" val identityCookie = "com.gu.identity" %% "identity-cookie" % identityLibVersion val identityModel = "com.gu.identity" %% "identity-model" % identityLibVersion @@ -32,7 +31,7 @@ object Dependencies { val jacksonMapper = "org.codehaus.jackson" % "jackson-mapper-asl" % "1.9.6" val jodaTime = "joda-time" % "joda-time" % "2.2" val jSoup = "org.jsoup" % "jsoup" % "1.7.3" - val liftJson = "net.liftweb" %% "lift-json" % "2.5" + val liftJson = "net.liftweb" %% "lift-json" % "2.6-RC2" val mockito = "org.mockito" % "mockito-all" % "1.9.5" % Test val nScalaTime = "com.github.nscala-time" %% "nscala-time" % "1.2.0" val openCsv = "net.sf.opencsv" % "opencsv" % "2.3" @@ -46,11 +45,12 @@ object Dependencies { val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.11.5" % "test" val scalajTime = "org.scalaj" % "scalaj-time_2.10.2" % "0.7" val scalaTest = "org.scalatest" %% "scalatest" % "2.2.1" % Test + val scalaz = "org.scalaz" %% "scalaz-core" % "7.0.6" val seeGuice = "com.tzavellas" % "sse-guice" % "0.7.1" val seleniumJava = "org.seleniumhq.selenium" % "selenium-java" % seleniumVersion - val shadeMemcached = "com.bionicspirit" %% "shade" % "1.5.0" + val shadeMemcached = "com.bionicspirit" %% "shade" % "1.6.0" val slf4jExt = "org.slf4j" % "slf4j-ext" % slf4jVersion val snappyJava = "org.xerial.snappy" % "snappy-java" % "1.0.5.1" val uaDetectorResources = "net.sf.uadetector" % "uadetector-resources" % "2013.04" - val scalaTestPlus = "org.scalatestplus" % "play_2.10" % "1.3.0" % "test" + val scalaTestPlus = "org.scalatestplus" %% "play" % "1.2.0" % "test" } diff --git a/project/Frontend.scala b/project/Frontend.scala index 91870ee1ecf1..9a1da285ad12 100644 --- a/project/Frontend.scala +++ b/project/Frontend.scala @@ -14,30 +14,30 @@ object Frontend extends Build with Prototypes { val common = application("common").settings( libraryDependencies ++= Seq( - guardianConfiguration, - contentApiClient, akkaAgent, - jSoup, + apacheCommonsMath3, + awsSdk, + contentApiClient, + faciaScalaClient, + filters, + flexibleContentBlockToText, + flexibleContentBodyParser, + guardianConfiguration, jacksonCore, jacksonMapper, - awsSdk, + jSoup, + liftJson, + playGoogleAuth, quartzScheduler, - dnaCommon, - scalajTime, - apacheCommonsMath3, - shadeMemcached, rome, romeModules, - snappyJava, - liftJson, - playGoogleAuth, - flexibleContentBlockToText, - flexibleContentBodyParser, scalaCheck, - faciaScalaClient, - filters, - ws, - scalaTestPlus + scalajTime, + scalaTestPlus, + scalaz, + shadeMemcached, + snappyJava, + ws ) ).settings( mappings in TestAssets ~= filterAssets @@ -177,13 +177,15 @@ object Frontend extends Build with Prototypes { weather ) - val integrationTests = Project("integrated-tests", file("integrated-tests")).settings( - libraryDependencies ++= Seq( - scalaTest, - seleniumJava % Test, - jodaTime % Test + val integrationTests = Project("integrated-tests", file("integrated-tests")) + .settings(frontendCompilationSettings:_*) + .settings( + libraryDependencies ++= Seq( + scalaTest, + seleniumJava % Test, + jodaTime % Test + ) ) - ) val pngResizer = application("png-resizer") .dependsOn(commonWithTests) diff --git a/project/Prototypes.scala b/project/Prototypes.scala index 555693bd7e9d..7fa69b59ea00 100644 --- a/project/Prototypes.scala +++ b/project/Prototypes.scala @@ -23,7 +23,9 @@ trait Prototypes { "-Xcheckinit", "-encoding", "utf8", "-feature", "-Yinline-warnings", "-Xfatal-warnings" ), - doc in Compile <<= target.map(_ / "none") + doc in Compile <<= target.map(_ / "none"), + incOptions := incOptions.value.withNameHashing(true), + scalaVersion := "2.11.4" ) val frontendDependencyManagementSettings = Seq( @@ -34,14 +36,9 @@ trait Prototypes { , - resolvers := Seq( - Resolver.typesafeRepo("releases"), - Classpaths.typesafeReleases, - "Akka" at "http://repo.akka.io/releases", + resolvers ++= Seq( + Resolver.sonatypeRepo("releases"), "Guardian Github Releases" at "http://guardian.github.com/maven/repo-releases", - "Guardian Github Snapshots" at "http://guardian.github.com/maven/repo-snapshots", - "JBoss Releases" at "https://repository.jboss.org/nexus/content/repositories/releases", - "BionicSpirit Releases" at "http://maven.bionicspirit.com/releases/", "Spy" at "https://files.couchbase.com/maven2/" ), @@ -89,6 +86,7 @@ trait Prototypes { ) def root() = Project("root", base = file(".")).enablePlugins(play.PlayScala) + .settings(frontendCompilationSettings:_*) def application(applicationName: String) = { Project(applicationName, file(applicationName)).enablePlugins(play.PlayScala) diff --git a/sport/app/football/feed/Competitions.scala b/sport/app/football/feed/Competitions.scala index e5e942bbe216..149681ad2432 100644 --- a/sport/app/football/feed/Competitions.scala +++ b/sport/app/football/feed/Competitions.scala @@ -126,7 +126,7 @@ trait Competitions extends LiveMatches with Logging with implicits.Collections w val competitionAgents = competitionDefinitions map { CompetitionAgent(_) } val competitionIds: Seq[String] = competitionDefinitions map { _.id } - private def competitions = competitionAgents.map(_.competition) + protected def competitions = competitionAgents.map(_.competition) def refreshCompetitionAgent(id: String) { competitionAgents find { _.competition.id == id } map { _.refresh() } diff --git a/sport/app/football/model/matches.scala b/sport/app/football/model/matches.scala index e7a4f5711c94..1bc79dcb9ea5 100644 --- a/sport/app/football/model/matches.scala +++ b/sport/app/football/model/matches.scala @@ -10,7 +10,7 @@ import football.collections.RichList import conf.Switches -trait MatchesList extends Football with RichList { +trait MatchesList extends Football with RichList with implicits.Collections { // container for all competitions val competitions: CompetitionSupport @@ -43,7 +43,7 @@ trait MatchesList extends Football with RichList { lazy val relevantMatches: List[(FootballMatch, Competition)] = { val startDate = date val matchDates = allRelevantMatches.map { case (fMatch, _) => fMatch.date.toLocalDate }.distinct - val eligibleDates = matchDates.dropWhile(dateComesFirstInList(_, startDate)).take(daysToDisplay) + val eligibleDates = matchDates.safeDropWhile(dateComesFirstInList(_, startDate)).take(daysToDisplay) allRelevantMatches.filter { case (fMatch, _) => eligibleDates.contains(fMatch.date.toLocalDate) } @@ -60,7 +60,7 @@ trait MatchesList extends Football with RichList { } lazy val nextPage: Option[String] = { - val nextMatchDate = matchDates.dropWhile(dateComesFirstInList(_, date)).drop(daysToDisplay).headOption + val nextMatchDate = matchDates.safeDropWhile(dateComesFirstInList(_, date)).drop(daysToDisplay).headOption nextMatchDate.map(s"$baseUrl/more/" + _.toString("yyyy/MMM/dd")) } lazy val previousPage: Option[String] = { diff --git a/sport/test/CompetitionAgentTest.scala b/sport/test/CompetitionAgentTest.scala index 64a2e9168f82..d167780b342c 100644 --- a/sport/test/CompetitionAgentTest.scala +++ b/sport/test/CompetitionAgentTest.scala @@ -68,7 +68,7 @@ import org.joda.time.LocalDate override val competitionAgents = Seq( CompetitionAgent(Competition("100", "/football/premierleague", "Premier League", "Premier League", "English", showInTeamsList = true)) ) - def competitions = competitionAgents.map(_.competition) + override def competitions = competitionAgents.map(_.competition) } TestCompetitions.competitionAgents.foreach(_.refresh())