Skip to content

Commit dcb49bd

Browse files
Consolidate tests and remove redundant package object rewriting
The PR #1 fix (.withMods preserving Package flag on ModuleDef) is the proper solution for package object support — remove our PackageDef rewriting workaround which broke nested package object type visibility. Merge NewTypeApiTest into NewTypeMacrosTest (Coercible wrapM/unwrapM, unsafeWrapMM, parameterized accessor, instance method chaining) and NewTypeCatsTest (Order.by/Show.show/Eq.by companion patterns). Remove the now-empty duplicate file.
1 parent 940b0bf commit dcb49bd

4 files changed

Lines changed: 58 additions & 166 deletions

File tree

plugin/src/main/scala/io/estatico/newtype/compat/NewTypeTreeTransformer.scala

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -298,16 +298,7 @@ class NewTypeTreeTransformer extends UntypedTreeMap:
298298

299299
override def transform(tree: Tree)(using Context): Tree = tree match
300300
case PackageDef(pid, stats) =>
301-
val transformedPid = transform(pid).asInstanceOf[RefTree]
302-
stats.partition { case md: ModuleDef => md.mods.is(Package); case _ => false } match
303-
case (pkgObj :: Nil, otherStats) =>
304-
val md = pkgObj.asInstanceOf[ModuleDef]
305-
val innerBody = transformStats(md.impl.body)
306-
val allInnerStats = otherStats.map(transform) ++ innerBody
307-
val newPid = Select(transformedPid, md.name)
308-
untpd.PackageDef(newPid, allInnerStats)
309-
case _ =>
310-
cpy.PackageDef(tree)(transformedPid, transformStats(stats))
301+
cpy.PackageDef(tree)(transform(pid).asInstanceOf[RefTree], transformStats(stats))
311302
case Block(stats, expr) =>
312303
cpy.Block(tree)(transformStats(stats), transform(expr))
313304
case td @ TypeDef(name, rhs: Template) if !findNewTypeAnnotation(td).isDefined =>

tests/src/test/scala/io/estatico/newtype/NewTypeApiTest.scala

Lines changed: 0 additions & 153 deletions
This file was deleted.

tests/src/test/scala/io/estatico/newtype/NewTypeCatsTest.scala

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ package io.estatico.newtype
22

33
import io.estatico.newtype.macros._
44
import io.estatico.newtype.ops._
5+
import cats.{Eq, Order, Show}
56
import org.scalatest.flatspec.AnyFlatSpec
67
import org.scalatest.matchers.should.Matchers
7-
import cats._
8-
import cats.syntax.all._
98

109
class NewTypeCatsTest extends AnyFlatSpec with Matchers {
1110

@@ -14,7 +13,6 @@ class NewTypeCatsTest extends AnyFlatSpec with Matchers {
1413
behavior of "@newtype with cats"
1514

1615
it should "derive Eq instance" in {
17-
implicit val eqInt: Eq[Int] = Eq.fromUniversalEquals
1816
val eqFoo: Eq[Foo] = Foo.deriving[Eq]
1917
eqFoo.eqv(Foo(1), Foo(1)) shouldBe true
2018
eqFoo.eqv(Foo(1), Foo(2)) shouldBe false
@@ -31,8 +29,37 @@ class NewTypeCatsTest extends AnyFlatSpec with Matchers {
3129
val i: Int = foo.coerce[Int]
3230
i shouldBe 42
3331
}
32+
33+
it should "resolve Order.by(_.value) in companion" in {
34+
val ord = implicitly[Order[Name]]
35+
ord.compare(Name("Alice"), Name("Bob")) should be < 0
36+
ord.compare(Name("Bob"), Name("Alice")) should be > 0
37+
ord.compare(Name("Alice"), Name("Alice")) shouldBe 0
38+
}
39+
40+
it should "resolve Show.show(_.value) in companion" in {
41+
val show = implicitly[Show[Name]]
42+
show.show(Name("Alice")) shouldBe "Alice"
43+
}
44+
45+
it should "resolve Eq.by(_.value) in companion" in {
46+
val eq = implicitly[Eq[Score]]
47+
eq.eqv(Score(10), Score(10)) shouldBe true
48+
eq.eqv(Score(10), Score(20)) shouldBe false
49+
}
3450
}
3551

3652
object NewTypeCatsTest {
3753
@newtype case class Foo(x: Int)
54+
55+
@newtype case class Name(value: String)
56+
object Name {
57+
implicit val orderForName: Order[Name] = Order.by(_.value)
58+
implicit val showForName: Show[Name] = Show.show(_.value)
59+
}
60+
61+
@newtype case class Score(value: Int)
62+
object Score {
63+
implicit val eqForScore: Eq[Score] = Eq.by(_.value)
64+
}
3865
}

tests/src/test/scala/io/estatico/newtype/macros/NewTypeMacrosTest.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class NewTypeMacrosTest extends AnyFlatSpec with Matchers {
2828
x.coerce[List[Int]] shouldBe List(1, 2, 3)
2929
}
3030

31+
it should "provide field accessor for parameterized newtype" in {
32+
val x = Baz(List("a", "b"))
33+
x.xs shouldBe List("a", "b")
34+
}
35+
3136
it should "support deriving" in {
3237
implicit val showInt: Show[Int] = (a: Int) => a.toString
3338
val showFoo: Show[Foo] = Foo.deriving[Show]
@@ -39,6 +44,12 @@ class NewTypeMacrosTest extends AnyFlatSpec with Matchers {
3944
x.plus(5) shouldBe HasMethods(15)
4045
}
4146

47+
it should "support instance methods with chaining" in {
48+
val c = HasMethods(0)
49+
c.increment shouldBe HasMethods(1)
50+
c.increment.increment shouldBe HasMethods(2)
51+
}
52+
4253
it should "support unapply when enabled" in {
4354
val x = WithUnapply(99)
4455
val result = x match {
@@ -65,6 +76,8 @@ class NewTypeMacrosTest extends AnyFlatSpec with Matchers {
6576
x.coerce[Int] shouldBe 7
6677
}
6778

79+
behavior of "Coercible"
80+
6881
it should "support Coercible wrapping/unwrapping" in {
6982
val w = implicitly[Coercible[Int, Foo]]
7083
val u = implicitly[Coercible[Foo, Int]]
@@ -78,6 +91,19 @@ class NewTypeMacrosTest extends AnyFlatSpec with Matchers {
7891
val int = foo.coerce[Int]
7992
int shouldBe 42
8093
}
94+
95+
it should "provide implicit wrapM and unwrapM" in {
96+
val wm = implicitly[Coercible[List[Int], List[Foo]]]
97+
val um = implicitly[Coercible[List[Foo], List[Int]]]
98+
val foos = wm(List(1, 2))
99+
um(foos) shouldBe List(1, 2)
100+
}
101+
102+
it should "coerce nested type constructors via Coercible.unsafeWrapMM" in {
103+
val nested: Option[List[Int]] = Some(List(1, 2, 3))
104+
val coerced = implicitly[Coercible[Option[List[Int]], Option[List[Foo]]]].apply(nested)
105+
coerced shouldBe Some(List(1, 2, 3))
106+
}
81107
}
82108

83109
object NewTypeMacrosTest {
@@ -93,6 +119,7 @@ object NewTypeMacrosTest {
93119

94120
@newtype case class HasMethods(value: Int) {
95121
def plus(other: Int): HasMethods = HasMethods(value + other)
122+
def increment: HasMethods = HasMethods(value + 1)
96123
}
97124

98125
@newtype(unapply = true) case class WithUnapply(x: Int)

0 commit comments

Comments
 (0)