From c73220cf589b54cd6d3485f120bd2f24da4f2a70 Mon Sep 17 00:00:00 2001 From: hughsimpson Date: Thu, 14 Nov 2024 18:38:19 +0000 Subject: [PATCH] Permit mocking stackable trait pattern in scala 3 (#528) * exclude artifact methods from generation * address comments (improve implementation, add more tests) --- .../scala-3/org/scalamock/clazz/Utils.scala | 1 + .../AbstractOverrideMethodTest.scala | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 shared/src/test/scala/org/scalamock/test/scalatest/AbstractOverrideMethodTest.scala diff --git a/shared/src/main/scala-3/org/scalamock/clazz/Utils.scala b/shared/src/main/scala-3/org/scalamock/clazz/Utils.scala index c274f08e..48e19810 100644 --- a/shared/src/main/scala-3/org/scalamock/clazz/Utils.scala +++ b/shared/src/main/scala-3/org/scalamock/clazz/Utils.scala @@ -178,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.flags.is(Flags.Artifact) && sym.privateWithin.isEmpty && !sym.name.contains("$default$") ) diff --git a/shared/src/test/scala/org/scalamock/test/scalatest/AbstractOverrideMethodTest.scala b/shared/src/test/scala/org/scalamock/test/scalatest/AbstractOverrideMethodTest.scala new file mode 100644 index 00000000..d68d0246 --- /dev/null +++ b/shared/src/test/scala/org/scalamock/test/scalatest/AbstractOverrideMethodTest.scala @@ -0,0 +1,55 @@ +// 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.test.scalatest + +import org.scalamock.scalatest.MockFactory +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +class AbstractOverrideMethodTest extends AnyFlatSpec with Matchers with MockFactory { + class A extends B with D + trait B extends C { + def foo(): Int = 1 + def bar[T](seq: Seq[T]): Seq[String] = seq.map(_.toString) + override def baz(a: String, b: Int): Int = a.size + b + } + trait C { + def foo(): Int + def bar[T](seq: Seq[T]): Seq[String] + def baz(a: String, b: Int): Int = (a.size * 2) + b + } + trait D extends C { + abstract override def foo(): Int = super.foo() * 2 + abstract override def bar[T](seq: Seq[T]): Seq[String] = "first" +: super.bar(seq) :+ "last" + abstract override def baz(a: String, b: Int): Int = super.baz(a, b) + 1 + } + + "ScalaTest suite" should "permit mocking classes build with stackable trait pattern" in { + val mockedClass = mock[A] + (mockedClass.foo _).expects().returning(42) + (mockedClass.bar _).expects(*).returning(Seq("a", "b", "c")) + (mockedClass.baz _).expects("A", 1).returning(2) + (mockedClass.baz _).expects("B", 1).never() + mockedClass.foo() shouldBe 42 + mockedClass.bar(Seq(1,2,3)) shouldBe Seq("a", "b", "c") + mockedClass.baz("A", 1) shouldBe 2 + } +}