diff --git a/build.sbt b/build.sbt index c6a6ffa63..2a82bd450 100644 --- a/build.sbt +++ b/build.sbt @@ -22,9 +22,8 @@ ThisBuild / version := Properties.envOrElse("VERSION", "0.0.0-dev") + (if ((ThisBuild / isSnapshot ).value) "-SNAPSHOT" else "") ThisBuild / isSnapshot := Properties.envOrElse("IS_SNAPSHOT","true").toBoolean ThisBuild / organization := "org.apache.toree.kernel" -ThisBuild / crossScalaVersions := Seq("2.13.8", "2.12.15") -//ThisBuild / crossScalaVersions := Seq("2.12.15", "2.13.8") -ThisBuild / scalaVersion := (ThisBuild / crossScalaVersions).value.head +ThisBuild / crossScalaVersions := Seq("2.12.15", "2.13.8") +ThisBuild / scalaVersion := (ThisBuild / crossScalaVersions).value.last ThisBuild / Dependencies.sparkVersion := { val envVar = "APACHE_SPARK_VERSION" val defaultVersion = "3.3.2" diff --git a/client/src/test/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClientSpec.scala b/client/src/test/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClientSpec.scala index 59359e676..d7534b02f 100644 --- a/client/src/test/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClientSpec.scala +++ b/client/src/test/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClientSpec.scala @@ -36,7 +36,7 @@ import org.mockito.ArgumentMatchers.{eq => mockEq, _} import org.mockito.Mockito._ import org.scalatest.concurrent.{Eventually, ScalaFutures} import org.scalatestplus.mockito.MockitoSugar -import org.scalatest.time.{Milliseconds, Span} +import org.scalatest.time.{Milliseconds, Seconds, Span} import org.scalatest.funspec.AnyFunSpecLike import org.scalatest.matchers.should.Matchers import org.scalatest.BeforeAndAfterEach @@ -60,7 +60,7 @@ class IOPubClientSpec extends TestKit(ActorSystem( { private val TestTimeout = Timeout(10.seconds) implicit override val patienceConfig = PatienceConfig( - timeout = scaled(Span(200, Milliseconds)), + timeout = scaled(Span(1, Seconds)), interval = scaled(Span(5, Milliseconds)) ) private val SignatureEnabled = true diff --git a/kernel/src/main/scala/org/apache/toree/utils/DataFrameConverter.scala b/kernel/src/main/scala/org/apache/toree/utils/DataFrameConverter.scala index ba75daa21..5ea98c3c2 100644 --- a/kernel/src/main/scala/org/apache/toree/utils/DataFrameConverter.scala +++ b/kernel/src/main/scala/org/apache/toree/utils/DataFrameConverter.scala @@ -21,6 +21,8 @@ import org.apache.spark.sql.{Dataset, Row} import org.apache.toree.plugins.Plugin import play.api.libs.json.{JsObject, Json} +import scala.collection.immutable +import scala.collection.mutable import scala.util.Try import org.apache.toree.plugins.annotations.Init @@ -84,7 +86,8 @@ object DataFrameConverter { def fieldToString(any: Any): String = any match { case null => "null" - case seq: Seq[_] => seq.mkString("[", ", ", "]") + case seq: immutable.Seq[_] => seq.mkString("[", ", ", "]") + case seq: mutable.Seq[_] => seq.mkString("[", ", ", "]") case _ => any.toString } diff --git a/plugins/src/test/scala-2.12/org/apache/toree/plugins/ClassFinderHelper.scala b/plugins/src/test/scala-2.12/org/apache/toree/plugins/ClassFinderHelper.scala new file mode 100644 index 000000000..81b7c95e7 --- /dev/null +++ b/plugins/src/test/scala-2.12/org/apache/toree/plugins/ClassFinderHelper.scala @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package org.apache.toree.plugins + +import org.clapper.classutil.ClassInfo + +trait ClassFinderHelper { + + def wrappedGetClassesReturnVal(classes: Seq[ClassInfo]): Object = { + classes.toStream + } +} diff --git a/plugins/src/test/scala-2.13/org/apache/toree/plugins/ClassFinderHelper.scala b/plugins/src/test/scala-2.13/org/apache/toree/plugins/ClassFinderHelper.scala new file mode 100644 index 000000000..ea7251554 --- /dev/null +++ b/plugins/src/test/scala-2.13/org/apache/toree/plugins/ClassFinderHelper.scala @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package org.apache.toree.plugins + +import org.clapper.classutil.ClassInfo + +trait ClassFinderHelper { + + def wrappedGetClassesReturnVal(classes: Seq[ClassInfo]): Object = { + LazyList.from(classes) + } +} diff --git a/plugins/src/test/scala/org/apache/toree/plugins/PluginSearcherSpec.scala b/plugins/src/test/scala/org/apache/toree/plugins/PluginSearcherSpec.scala index 36e46ee4b..4df4d6423 100644 --- a/plugins/src/test/scala/org/apache/toree/plugins/PluginSearcherSpec.scala +++ b/plugins/src/test/scala/org/apache/toree/plugins/PluginSearcherSpec.scala @@ -17,8 +17,9 @@ package org.apache.toree.plugins import java.io.File +import scala.collection.immutable -import org.clapper.classutil.{Modifier, ClassFinder} +import org.clapper.classutil.{ClassFinder, Modifier} import org.scalatestplus.mockito.MockitoSugar import org.scalatest.OneInstancePerTest import org.scalatest.funspec.AnyFunSpec @@ -27,8 +28,9 @@ import org.scalatest.matchers.should.Matchers import org.mockito.Mockito._ import test.utils.TestClassInfo + class PluginSearcherSpec extends AnyFunSpec with Matchers - with OneInstancePerTest with MockitoSugar + with OneInstancePerTest with MockitoSugar with ClassFinderHelper { private val mockClassFinder = mock[ClassFinder] private val pluginSearcher = new PluginSearcher { @@ -65,7 +67,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers name = "abstract.plugin", modifiers = Set(Modifier.Abstract) ) - private val classInfos = Seq( + private val classInfos = immutable.Seq( pluginClassInfo, directPluginClassInfo, directAsInterfacePluginClassInfo, indirectPluginClassInfo, indirectAsInterfacePluginClassInfo, @@ -77,7 +79,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers it("should find any plugins directly extending the Plugin class") { val expected = directPluginClassInfo.name - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.internal.map(_.name) @@ -87,7 +89,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers it("should find any plugins directly extending the Plugin trait") { val expected = directAsInterfacePluginClassInfo.name - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.internal.map(_.name) @@ -97,7 +99,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers it("should find any plugins indirectly extending the Plugin class") { val expected = indirectPluginClassInfo.name - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.internal.map(_.name) @@ -107,7 +109,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers it("should find any plugins indirectly extending the Plugin trait") { val expected = indirectAsInterfacePluginClassInfo.name - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.internal.map(_.name) @@ -120,7 +122,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers traitPluginClassInfo.name ) - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.internal.map(_.name) @@ -132,7 +134,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers it("should find any plugins directly extending the Plugin class") { val expected = directPluginClassInfo.name - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.search().map(_.name).toSeq @@ -142,7 +144,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers it("should find any plugins directly extending the Plugin trait") { val expected = directAsInterfacePluginClassInfo.name - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.search().map(_.name).toSeq @@ -152,7 +154,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers it("should find any plugins indirectly extending the Plugin class") { val expected = indirectPluginClassInfo.name - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.search().map(_.name).toSeq @@ -162,7 +164,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers it("should find any plugins indirectly extending the Plugin trait") { val expected = indirectAsInterfacePluginClassInfo.name - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.search().map(_.name).toSeq @@ -175,7 +177,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers traitPluginClassInfo.name ) - doReturn(classInfos.toStream, Nil: _*).when(mockClassFinder).getClasses() + doReturn(wrappedGetClassesReturnVal(classInfos), Nil: _*).when(mockClassFinder).getClasses() val actual = pluginSearcher.search().map(_.name).toSeq diff --git a/scala-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/scala/ScalaInterpreter.scala b/scala-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/scala/ScalaInterpreter.scala index f83365d74..21c3ddebc 100644 --- a/scala-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/scala/ScalaInterpreter.scala +++ b/scala-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/scala/ScalaInterpreter.scala @@ -213,7 +213,7 @@ class ScalaInterpreter(private val config:Config = ConfigFactory.load) extends I definitions.append(s"$name: $func$funcType").append("\n") - case NamedResult(name, vtype, value) if read(name).nonEmpty => + case NamedResult(_, _, name, vtype, value) if read(name).nonEmpty => val result = read(name) @@ -419,7 +419,7 @@ class ScalaInterpreter(private val config:Config = ConfigFactory.load) extends I object ScalaInterpreter { val HigherOrderFunction: Regex = """(\w+):\s+(\(\s*.*=>\s*\w+\))(\w+)\s*.*""".r - val NamedResult: Regex = """(\w+):\s+([^=]+)\s+=\s*(.*)""".r + val NamedResult: Regex = """((val|var)\s+)?(\w+):\s+([^=]+)\s+=\s*(.*)""".r val Definition: Regex = """defined\s+(\w+)\s+(.+)""".r val Import: Regex = """import\s+([\w\.,\{\}\s]+)""".r