Skip to content

Commit

Permalink
mocks reimplemented for scala 3
Browse files Browse the repository at this point in the history
  • Loading branch information
goshacodes committed Sep 7, 2023
1 parent a7d15bd commit ae0e308
Show file tree
Hide file tree
Showing 9 changed files with 578 additions and 6 deletions.
6 changes: 3 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ lazy val scalatest = Def.setting("org.scalatest" %%% "scalatest" % "3.2.16")
lazy val specs2 = Def.setting("org.specs2" %%% "specs2-core" % "4.20.2")

val commonSettings = Defaults.coreDefaultSettings ++ Seq(
scalaVersion := "2.13.11",
scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature", "-Xcheckinit", "-release:8")
scalaVersion := "3.3.0",
scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature", "-release:8")
)

lazy val scalamock = crossProject(JSPlatform, JVMPlatform) in file(".") settings(
Expand Down Expand Up @@ -48,7 +48,7 @@ def crossScalaSettings = {
}
}
Seq(
crossScalaVersions := Seq("2.12.17", scalaVersion.value),
crossScalaVersions := Seq("2.12.17", "2.13.11", scalaVersion.value),
Compile / unmanagedSourceDirectories ++= addDirsByScalaVersion("src/main").value,
Test / unmanagedSourceDirectories ++= addDirsByScalaVersion("src/test").value,
libraryDependencies ++= {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2011-2015 ScalaMock Contributors (https://github.com/paulbutcher/ScalaMock/graphs/contributors)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package org.scalamock.clazz

import scala.quoted.*

object MockFunctionFinderImpl:
def find[M: Type](obj: Expr[AnyRef], name: String)(using quotes: Quotes): Expr[M] =
import quotes.reflect.*
Typed(
Apply(
Select.unique('{${obj}.asInstanceOf[scala.reflect.Selectable]}.asTerm, "selectDynamic"),
List(Expr(name).asTerm)
),
TypeTree.of[M]
).asExprOf[M]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2011-2015 ScalaMock Contributors (https://github.com/paulbutcher/ScalaMock/graphs/contributors)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package org.scalamock.clazz

import scala.quoted.*

object MockFunctionFinderImpl:
def find[M: Type](obj: Expr[AnyRef], name: String)(using quotes: Quotes): Expr[M] =
import quotes.reflect.*
'{${obj}.getClass.getMethod(${Expr(name)}).invoke(${obj}).asInstanceOf[M]}.asExprOf[M]

84 changes: 84 additions & 0 deletions shared/src/main/scala-3/org/scalamock/clazz/Mock.scala

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2011-2015 ScalaMock Contributors (https://github.com/paulbutcher/ScalaMock/graphs/contributors)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package org.scalamock.clazz

import scala.quoted.*

object MockFunctionFinder:
def ticketMessage = "Please open a ticket at https://github.com/paulbutcher/ScalaMock/issues"
/**
* Given something of the structure <|o.m _|> where o is a mock object
* and m is a method, find the corresponding MockFunction instance
*/
def findMockFunction[F: Type, M: Type](f: Expr[F], actuals: List[Any])(using quotes: Quotes): Expr[M] =
import quotes.reflect.*
def findMockFunctionName(term: Term, name: String, targs: List[TypeTree]): String =
"mock$" + name + "$" + TypeRepr.of[M].typeArgs.init.map(_.show(using Printer.TypeReprShortCode)).mkString("[", ",", "]")

def transcribeTree(term: Term, types: List[TypeTree] = Nil): Expr[M] =
term match
case Select(mock, methodName) =>
val name = findMockFunctionName(mock, methodName, types)
Typed(
Apply(
Select.unique('{ ${ mock.asExpr }.asInstanceOf[scala.reflect.Selectable] }.asTerm, "selectDynamic"),
List(Expr(name).asTerm)
),
TypeTree.of[M]
).asExprOf[M]

case Inlined(_, _, term) => transcribeTree(term)
case ident: Ident => transcribeTree(ident.underlying)
case Block(List(DefDef(_, _, _, Some(term))), _) => transcribeTree(term)
case full @ Block(List(ValDef(_, _, Some(term))), _) => transcribeTree(term)
case Typed(term, _) => transcribeTree(term)
case Lambda(_, term) => transcribeTree(term)
case Apply(term, name) => transcribeTree(term)
case TypeApply(term, types) => transcribeTree(term, types)
case _ =>
report.errorAndAbort(
s"ScalaMock: unrecognised structure ${term.show(using Printer.TreeStructure)}. " ++ ticketMessage
)
transcribeTree(f.asTerm)
Loading

0 comments on commit ae0e308

Please sign in to comment.