Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion project/BuildHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ object BuildHelper {
case Some((2, 13)) =>
List("2.13+", "2.12-2.13")
case Some((3, _)) =>
List("2.13+")
List("2.13+", "3")
case _ =>
List()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package zio.test

object SmartAssertionScala3Spec extends ZIOBaseSpec {

override def spec =
suite("SmartAssertionScala3Spec")(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this only contain Scala 3 specific tests? Do we need the overlap with SmartAssertionSpec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, only specific to scala 3 test cases.

  1. trait with parameters
  2. inlines
  3. assertTrue with anonymous classes not compiled with scala 2 and it looked like scala 2 problem itself

If you have any suggestions on improving it - I can do it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I didn't think about traits with parameters not being available on Scala 2. Thanks for the clarification.

suite("new instance creation")(
test("anonymous class (trait) with overload and type args - new instance") {
trait ClassWithOverload[X] {
def overloaded: Int = 1
def overloaded(x: Int): Int = 1
}
assertTrue(new ClassWithOverload[Int]() {}.overloaded == 1)
},
test("anonymous class with overload - new instance") {
class ClassWithOverload {
def overloaded: Int = 1
def overloaded(x: Int): Int = 1
}
assertTrue(new ClassWithOverload() {}.overloaded == 1)
},
test("anonymous class (trait) with overload - new instance") {
trait ClassWithOverload {
def overloaded: Int = 1
def overloaded(x: Int): Int = 1
}
assertTrue(new ClassWithOverload() {}.overloaded == 1)
},
test("trait with parameter and overloaded methods") {
trait TraitOverloadedWithParameter(x: Int) {
def overloaded: Int = 1

def overloaded(x: Int) = 1
}

assertTrue(new TraitOverloadedWithParameter(1) {}.overloaded == 1)
},
test("trait with overloaded methods with type args") {
trait TraitOverloadedAndTypeArgs[A] {
def overloaded: Int = 1

def overloaded(x: Int) = 1
}

assertTrue(new TraitOverloadedAndTypeArgs[Int] {}.overloaded == 1)
},
test("trait with parameter and overloaded methods with type args") {
trait TraitOverloadedWithParameterAndTypeArgs[A](x: A) {
def overloaded: Int = 1

def overloaded(x: Int) = 1
}

assertTrue(new TraitOverloadedWithParameterAndTypeArgs[Int](1) {}.overloaded == 1)
},
test("inlined trait with overloaded methods and parameter and type arg") {
trait TraitOverloadedWithParameterAndTypeArgs[A](x: A) {
def overloaded: Int = 1

def overloaded(x: Int) = 1
}
@scala.annotation.nowarn
inline def create = new TraitOverloadedWithParameterAndTypeArgs[Int](1) {}

assertTrue(create.overloaded == 1)
},
test("inlined trait with overloaded methods and parameter") {
trait TraitOverloadedWithParameter(x: Int) {
def overloaded: Int = 1

def overloaded(x: Int) = 1
}
@scala.annotation.nowarn
inline def create =
new TraitOverloadedWithParameter(1) {}

assertTrue(create.overloaded == 1)
},
test("inlined class with overloaded methods and parameter") {
class ClassOverloadedWithParameter(x: Int) {
def overloaded: Int = 1

def overloaded(x: Int) = 1
}

@scala.annotation.nowarn
inline def create =
new ClassOverloadedWithParameter(1)

assertTrue(create.overloaded == 1)
}
)
)

}
28 changes: 28 additions & 0 deletions test-tests/shared/src/test/scala/zio/test/SmartAssertionSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,34 @@ object SmartAssertionSpec extends ZIOBaseSpec {
val exit: Exit[String, Int] = Exit.succeed(1)
assertTrue(exit.isSuccess)
},
test("class with overload - new instance") {
class ClassWithOverload {
def overloaded: Int = 1
def overloaded(x: Int): Int = x
}
assertTrue(new ClassWithOverload().overloaded == 1)
},
test("class with overload with type args - new instance") {
class ClassWithOverload[A] {
def overloaded: Int = 1
def overloaded(x: Int): Int = x
}
assertTrue(new ClassWithOverload[Int]().overloaded == 1)
},
test("class with overload with args - new instance") {
class ClassWithOverload(x: Int) {
def overloaded: Int = x
def overloaded(x: Int): Int = x
}
assertTrue(new ClassWithOverload(1).overloaded == 1)
},
test("class with overload with args and type args - new instance") {
class ClassWithOverload[A](x: Int) {
def overloaded: Int = x
def overloaded(x: Int): Int = x
}
assertTrue(new ClassWithOverload[Int](1).overloaded == 1)
},
test("equalTo on java.lang.Boolean works") {
val jBool = java.lang.Boolean.FALSE
assertTrue(jBool == false)
Expand Down
43 changes: 28 additions & 15 deletions test/shared/src/main/scala-3/zio/test/Macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -345,29 +345,42 @@ object SmartAssertMacros {
}

case Unseal(method @ MethodCall(lhs, name, tpeArgs, args)) =>
def body(param: Term) =
def body(param: Term): Term =
(tpeArgs, args) match {
case (Nil, None) =>
try Select.unique(param, name)
catch {
case _: AssertionError =>
def getFieldOrMethod(s: Symbol) =
s.fieldMembers
def getFieldOrMethod(tpe: TypeRepr, owner: Tree): Select = {
val s = tpe.typeSymbol
val member = s.fieldMembers
.find(f => f.name == name)
.orElse(s.methodMember(name).filter(_.declarations.nonEmpty).headOption)
.getOrElse(
report.errorAndAbort(s"Could not resolve $name on ${owner.show(using Printer.TreeStructure)}")
)
Select(param, member)
}

// Tries to find directly the referenced method on lhs's type (or if lhs is method, on lhs's returned type)
lhs.symbol.tree match {
case DefDef(_, _, tpt, _) =>
getFieldOrMethod(tpt.symbol) match {
case Some(fieldOrMethod) => Select(param, fieldOrMethod)
case None => throw new Error(s"Could not resolve $name on $tpt")
}
case _ =>
getFieldOrMethod(lhs.symbol) match {
case Some(fieldOrMethod) => Select(param, fieldOrMethod)
case None => throw new Error(s"Could not resolve $name on $lhs")
}
lhs.underlyingArgument match {
case Block(List(cls: ClassDef), term) =>
// if this is new instance of anonymous class - take symbol from it instead of block
getFieldOrMethod(term.tpe, term)

case Typed(Block(List(cls: ClassDef), term), _) =>
getFieldOrMethod(term.tpe, term)

// Tries to find directly the referenced method on lhs's type (or if lhs is method, on lhs's returned type)
case lhs =>
if lhs.symbol == Symbol.noSymbol then
report.errorAndAbort(s"Can't get symbol of ${lhs.show(using Printer.TreeStructure)}")
else
lhs.symbol.tree match {
case DefDef(_, _, tpt, _) =>
getFieldOrMethod(tpt.tpe, tpt)
case _ =>
getFieldOrMethod(lhs.tpe, lhs)
}
}
}
case (tpeArgs, Some(args)) => Select.overloaded(param, name, tpeArgs, args)
Expand Down
Loading