Skip to content

Commit

Permalink
Merge branch 'paulbutcher:master' into fix-constructor-params
Browse files Browse the repository at this point in the history
  • Loading branch information
martijnhoekstra authored Jun 6, 2024
2 parents 3fe3d7c + 8de4b7b commit dabe3b1
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 6 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def crossScalaSettings = {
}
}
Seq(
crossScalaVersions := Seq("2.12.19", "2.13.12", scalaVersion.value),
crossScalaVersions := Seq("2.12.19", "2.13.14", 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,26 @@
// Copyright (c) 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 com.paulbutcher.test;

public class JavaClassWithDefaultAccess {
public JavaClassWithDefaultAccess(){}
int getSomeInt(){ return 1;}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 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.test.scalatest

import com.paulbutcher.test.JavaClassWithDefaultAccess
import org.scalamock.scalatest.MockFactory
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class DefaultAccessMockTest extends AnyFlatSpec with MockFactory with Matchers {
"mockign classes with members with JMV default access" should "work" in {
class DefaultExtended extends JavaClassWithDefaultAccess()
val m = mock[DefaultExtended]
}
}
17 changes: 12 additions & 5 deletions shared/src/main/scala-3/org/scalamock/clazz/Utils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ private[clazz] class Utils(using val quotes: Quotes):

def resolveAndOrTypeParamRefs: TypeRepr =
tpe match {
case AndType(left: ParamRef, right: ParamRef) =>
case AndType(left @ (_: ParamRef | _: AppliedType), right @ (_: ParamRef | _: AppliedType)) =>
TypeRepr.of[Any]
case AndType(left: ParamRef, right) =>
case AndType(left @ (_: ParamRef | _: AppliedType), right) =>
right.resolveAndOrTypeParamRefs
case AndType(left, right: ParamRef) =>
case AndType(left, right @ (_: ParamRef | _: AppliedType)) =>
left.resolveAndOrTypeParamRefs
case OrType(_: ParamRef, _) =>
case OrType(_: ParamRef | _: AppliedType, _) =>
TypeRepr.of[Any]
case OrType(_, _: ParamRef) =>
case OrType(_, _: ParamRef | _: AppliedType) =>
TypeRepr.of[Any]
case other =>
other
Expand All @@ -77,6 +77,12 @@ private[clazz] class Utils(using val quotes: Quotes):
case pr@ParamRef(bindings, idx) if bindings == baseBindings =>
methodArgs.head(idx).asInstanceOf[TypeTree].tpe

case AndType(left, right) =>
AndType(loop(left), loop(right))

case OrType(left, right) =>
OrType(loop(left), loop(right))

case AppliedType(tycon, args) =>
AppliedType(loop(tycon), args.map(arg => loop(arg)))

Expand Down Expand Up @@ -172,6 +178,7 @@ private[clazz] class Utils(using val quotes: Quotes):
!sym.flags.is(Flags.Private) &&
!sym.flags.is(Flags.Final) &&
!sym.flags.is(Flags.Mutable) &&
sym.privateWithin.isEmpty &&
!sym.name.contains("$default$")
)
.zipWithIndex
Expand Down
69 changes: 69 additions & 0 deletions shared/src/test/scala-3/com/paulbutcher/test/Scala3Spec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,75 @@ class Scala3Spec extends AnyFunSpec with MockFactory with Matchers {
m.methodWithGenericUnion(obj2)
}

it("mock union return type") {

trait A

trait B

trait TraitWithUnionReturnType {

def methodWithUnionReturnType[T](): T | A
}

val m = mock[TraitWithUnionReturnType]

val obj = new B {}

(() => m.methodWithUnionReturnType[B]()).expects().returns(obj)

m.methodWithUnionReturnType[B]() shouldBe obj
}

it("mock intersection return type") {

trait A

trait B

trait TraitWithIntersectionReturnType {

def methodWithIntersectionReturnType[T](): A & T
}

val m = mock[TraitWithIntersectionReturnType]

val obj = new A with B {}

(() => m.methodWithIntersectionReturnType[B]()).expects().returns(obj)

m.methodWithIntersectionReturnType[B]() shouldBe obj
}

it("mock intersection|union types with type constructors") {

trait A[T]

trait B

trait C

trait ComplexUnionIntersectionCases {

def complexMethod1[T](x: A[T] & T): A[T] & T
def complexMethod2[T](x: A[A[T]] | T): A[T] | T
def complexMethod3[F[_], T](x: F[A[T] & F[T]] | T & A[F[T]]): F[T] & T
def complexMethod4[T](x: A[B & C] ): A[B & C]
def complexMethod5[T](x: A[B | A[C]]): A[B | C]
}

val m = mock[ComplexUnionIntersectionCases]

val obj = new A[B] with B {}
val obj2 = new A[A[B]] with B {}

(m.complexMethod1[B] _).expects(obj).returns(obj)
(m.complexMethod2[B] _).expects(obj2).returns(new A[B] {})

m.complexMethod1[B](obj)
m.complexMethod2[B](obj2)
}

it("mock methods returning function") {
trait Test {
def method(x: Int): Int => String
Expand Down

0 comments on commit dabe3b1

Please sign in to comment.