Skip to content

Commit e1b1ee3

Browse files
committed
refactor(schema): migrate structural tests from typeName to typeCheck
Replace all typeName.contains() and typeName == assertions with typeCheck tests that verify structural type signatures compile correctly. Changes: - Remove typeName assertions from 13 test files - Delete TypeNameNormalizationSpec.scala (tests TypeName going away) - Preserve all runtime tests (roundtrips, Reflect structure checks) - Add typeCheck tests where needed for coverage This prepares for TypeName removal in a separate PR.
1 parent a4e2e04 commit e1b1ee3

14 files changed

+143
-312
lines changed

schema/jvm/src/test/scala-3/zio/blocks/schema/structural/EnumStructuralSpec.scala

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,28 @@ object EnumStructuralSpec extends ZIOSpecDefault {
2626
def spec = suite("EnumStructuralSpec")(
2727
suite("Structural Conversion")(
2828
test("simple enum converts to structural union type") {
29-
val schema = Schema.derived[Color]
30-
val structural = schema.structural
31-
val typeName = structural.reflect.typeName.name
32-
assertTrue(
33-
typeName.contains("Tag:\"Red\""),
34-
typeName.contains("Tag:\"Green\""),
35-
typeName.contains("Tag:\"Blue\""),
36-
typeName.contains("|")
37-
)
29+
typeCheck("""
30+
import zio.blocks.schema._
31+
enum Color { case Red, Green, Blue }
32+
val schema = Schema.derived[Color]
33+
val structural: Schema[{def Tag: "Blue"} | {def Tag: "Green"} | {def Tag: "Red"}] = schema.structural
34+
""").map(result => assertTrue(result.isRight))
3835
},
3936
test("parameterized enum converts to structural union type") {
40-
val schema = Schema.derived[Shape]
41-
val structural = schema.structural
42-
val typeName = structural.reflect.typeName.name
43-
assertTrue(
44-
typeName.contains("Tag:\"Circle\""),
45-
typeName.contains("Tag:\"Rectangle\""),
46-
typeName.contains("Tag:\"Triangle\""),
47-
typeName.contains("radius:Double"),
48-
typeName.contains("width:Double"),
49-
typeName.contains("base:Double"),
50-
typeName.contains("|")
51-
)
37+
typeCheck("""
38+
import zio.blocks.schema._
39+
enum Shape {
40+
case Circle(radius: Double)
41+
case Rectangle(width: Double, height: Double)
42+
case Triangle(base: Double, height: Double)
43+
}
44+
val schema = Schema.derived[Shape]
45+
val structural: Schema[
46+
{def Tag: "Circle"; def radius: Double} |
47+
{def Tag: "Rectangle"; def height: Double; def width: Double} |
48+
{def Tag: "Triangle"; def base: Double; def height: Double}
49+
] = schema.structural
50+
""").map(result => assertTrue(result.isRight))
5251
},
5352
test("structural enum schema is still a Variant") {
5453
val schema = Schema.derived[Status]
@@ -65,14 +64,6 @@ object EnumStructuralSpec extends ZIOSpecDefault {
6564
case v: Reflect.Variant[_, _] => v.cases.size
6665
}
6766
assertTrue(caseCount == 3)
68-
},
69-
test("enum converts to expected structural union type") {
70-
typeCheck("""
71-
import zio.blocks.schema._
72-
enum Color { case Red, Green, Blue }
73-
val schema = Schema.derived[Color]
74-
val structural: Schema[{def Tag: "Blue"} | {def Tag: "Green"} | {def Tag: "Red"}] = schema.structural
75-
""").map(result => assertTrue(result.isRight))
7667
}
7768
)
7869
)

schema/jvm/src/test/scala-3/zio/blocks/schema/structural/EnumToUnionSpec.scala

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,25 @@ object EnumToUnionSpec extends ZIOSpecDefault {
2727
}
2828

2929
def spec = suite("EnumToUnionSpec")(
30-
test("simple enum structural has exact union type name") {
31-
val schema = Schema.derived[Color]
32-
val structural = schema.structural
33-
val typeName = structural.reflect.typeName.name
34-
assertTrue(typeName == """{Tag:"Blue"}|{Tag:"Green"}|{Tag:"Red"}""")
30+
test("simple enum converts to structural union type") {
31+
typeCheck("""
32+
import zio.blocks.schema._
33+
enum Color { case Red, Green, Blue }
34+
val schema = Schema.derived[Color]
35+
val structural: Schema[{def Tag: "Blue"} | {def Tag: "Green"} | {def Tag: "Red"}] = schema.structural
36+
""").map(result => assertTrue(result.isRight))
3537
},
36-
test("parameterized enum structural has exact union type name with fields") {
37-
val schema = Schema.derived[Shape]
38-
val structural = schema.structural
39-
val typeName = structural.reflect.typeName.name
40-
assertTrue(
41-
typeName ==
42-
"""{Tag:"Circle",radius:Double}|{Tag:"Rectangle",height:Double,width:Double}|{Tag:"Triangle",base:Double,height:Double}"""
43-
)
38+
test("parameterized enum converts to structural union type with fields") {
39+
typeCheck("""
40+
import zio.blocks.schema._
41+
enum Shape {
42+
case Circle(radius: Double)
43+
case Rectangle(width: Double, height: Double)
44+
case Triangle(base: Double, height: Double)
45+
}
46+
val schema = Schema.derived[Shape]
47+
val structural: Schema[{def Tag: "Circle"; def radius: Double} | {def Tag: "Rectangle"; def height: Double; def width: Double} | {def Tag: "Triangle"; def base: Double; def height: Double}] = schema.structural
48+
""").map(result => assertTrue(result.isRight))
4449
},
4550
test("structural enum schema is a Variant") {
4651
val schema = Schema.derived[Color]
@@ -88,26 +93,6 @@ object EnumToUnionSpec extends ZIOSpecDefault {
8893
fields.toMap.get("radius").contains(DynamicValue.Primitive(PrimitiveValue.Double(5.0)))
8994
case _ => false
9095
})
91-
},
92-
test("simple enum converts to expected structural union type") {
93-
typeCheck("""
94-
import zio.blocks.schema._
95-
enum Color { case Red, Green, Blue }
96-
val schema = Schema.derived[Color]
97-
val structural: Schema[{def Tag: "Blue"} | {def Tag: "Green"} | {def Tag: "Red"}] = schema.structural
98-
""").map(result => assertTrue(result.isRight))
99-
},
100-
test("parameterized enum converts to expected structural union type") {
101-
typeCheck("""
102-
import zio.blocks.schema._
103-
enum Shape {
104-
case Circle(radius: Double)
105-
case Rectangle(width: Double, height: Double)
106-
case Triangle(base: Double, height: Double)
107-
}
108-
val schema = Schema.derived[Shape]
109-
val structural: Schema[{def Tag: "Circle"; def radius: Double} | {def Tag: "Rectangle"; def height: Double; def width: Double} | {def Tag: "Triangle"; def base: Double; def height: Double}] = schema.structural
110-
""").map(result => assertTrue(result.isRight))
11196
}
11297
)
11398
}

schema/jvm/src/test/scala-3/zio/blocks/schema/structural/OpaqueTypeUnpackingSpec.scala

Lines changed: 43 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -33,67 +33,56 @@ object OpaqueTypeUnpackingSpec extends ZIOSpecDefault {
3333
def spec = suite("OpaqueTypeUnpackingSpec")(
3434
suite("Simple opaque types are unpacked to primitives")(
3535
test("UserId (opaque String) is unpacked to String in structural type") {
36-
val schema = Schema.derived[User]
37-
val structural = schema.structural
38-
val typeName = structural.reflect.typeName.name
39-
assertTrue(
40-
typeName.contains("id:String"),
41-
typeName.contains("name:String"),
42-
!typeName.contains("UserId")
43-
)
36+
typeCheck("""
37+
import zio.blocks.schema._
38+
import zio.blocks.schema.structural.OpaqueTypeUnpackingSpec._
39+
val schema = Schema.derived[User]
40+
val structural: Schema[{def id: String; def name: String}] = schema.structural
41+
""").map(result => assertTrue(result.isRight))
4442
},
4543
test("Age (opaque Int) is unpacked to Int in structural type") {
46-
val schema = Schema.derived[Person]
47-
val structural = schema.structural
48-
val typeName = structural.reflect.typeName.name
49-
assertTrue(
50-
typeName.contains("age:Int"),
51-
typeName.contains("name:String"),
52-
!typeName.contains("Age")
53-
)
44+
typeCheck("""
45+
import zio.blocks.schema._
46+
import zio.blocks.schema.structural.OpaqueTypeUnpackingSpec.{Person => PersonType, _}
47+
val schema = Schema.derived[PersonType]
48+
val structural: Schema[{def age: Int; def name: String}] = schema.structural
49+
""").map(result => assertTrue(result.isRight))
5450
},
5551
test("Score (opaque Double) is unpacked to Double in structural type") {
56-
val schema = Schema.derived[GameResult]
57-
val structural = schema.structural
58-
val typeName = structural.reflect.typeName.name
59-
assertTrue(
60-
typeName.contains("score:Double"),
61-
typeName.contains("player:String"),
62-
!typeName.contains("Score")
63-
)
52+
typeCheck("""
53+
import zio.blocks.schema._
54+
import zio.blocks.schema.structural.OpaqueTypeUnpackingSpec._
55+
val schema = Schema.derived[GameResult]
56+
val structural: Schema[{def player: String; def score: Double}] = schema.structural
57+
""").map(result => assertTrue(result.isRight))
6458
}
6559
),
6660
suite("Nested opaque types are unpacked recursively")(
6761
test("nested case class with opaque fields is fully unpacked") {
68-
val schema = Schema.derived[NestedOpaque]
69-
val structural = schema.structural
70-
val typeName = structural.reflect.typeName.name
71-
assertTrue(
72-
typeName.contains("score:Double"),
73-
typeName.contains("user:"),
74-
!typeName.contains("Score"),
75-
!typeName.contains("UserId")
76-
)
62+
typeCheck("""
63+
import zio.blocks.schema._
64+
import zio.blocks.schema.structural.OpaqueTypeUnpackingSpec._
65+
val schema = Schema.derived[NestedOpaque]
66+
val structural: Schema[{def score: Double; def user: User}] = schema.structural
67+
""").map(result => assertTrue(result.isRight))
7768
}
7869
),
7970
suite("Opaque types in collections are unpacked")(
8071
test("List[UserId] field appears in structural type") {
81-
val schema = Schema.derived[ListOfOpaque]
82-
val structural = schema.structural
83-
val typeName = structural.reflect.typeName.name
84-
assertTrue(
85-
typeName.contains("ids:List"),
86-
!typeName.contains("UserId")
87-
)
72+
typeCheck("""
73+
import zio.blocks.schema._
74+
import zio.blocks.schema.structural.OpaqueTypeUnpackingSpec._
75+
val schema = Schema.derived[ListOfOpaque]
76+
val structural: Schema[{def ids: List[String]}] = schema.structural
77+
""").map(result => assertTrue(result.isRight))
8878
},
8979
test("Option[UserId] field appears in structural type") {
90-
val schema = Schema.derived[OptionalOpaque]
91-
val structural = schema.structural
92-
val typeName = structural.reflect.typeName.name
93-
assertTrue(
94-
typeName.contains("maybeId:Option"),
95-
!typeName.contains("UserId")
96-
)
80+
typeCheck("""
81+
import zio.blocks.schema._
82+
import zio.blocks.schema.structural.OpaqueTypeUnpackingSpec._
83+
val schema = Schema.derived[OptionalOpaque]
84+
val structural: Schema[{def maybeId: Option[String]}] = schema.structural
85+
""").map(result => assertTrue(result.isRight))
9786
}
9887
),
9988
suite("Structural schema round-trip with opaque types")(
@@ -106,14 +95,13 @@ object OpaqueTypeUnpackingSpec extends ZIOSpecDefault {
10695

10796
assertTrue(roundTrip == Right(original))
10897
},
109-
test("structural schema of User has correct type name") {
110-
val schema = Schema.derived[User]
111-
val structural = schema.structural
112-
val typeName = structural.reflect.typeName.name
113-
assertTrue(
114-
typeName.contains("id:String"),
115-
typeName.contains("name:String")
116-
)
98+
test("structural schema of User has correct type") {
99+
typeCheck("""
100+
import zio.blocks.schema._
101+
import zio.blocks.schema.structural.OpaqueTypeUnpackingSpec._
102+
val schema = Schema.derived[User]
103+
val structural: Schema[{def id: String; def name: String}] = schema.structural
104+
""").map(result => assertTrue(result.isRight))
117105
}
118106
),
119107
suite("Type checking with explicit structural types")(

schema/jvm/src/test/scala-3/zio/blocks/schema/structural/SealedTraitToUnionSpec.scala

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,16 @@ object SealedTraitToUnionSpec extends ZIOSpecDefault {
3333

3434
def spec = suite("SealedTraitToUnionSpec")(
3535
test("sealed trait structural has exact union type name") {
36-
val schema = Schema.derived[Result]
37-
val structural = schema.structural
38-
val typeName = structural.reflect.typeName.name
39-
assertTrue(typeName == """{Tag:"Failure",error:String}|{Tag:"Success",value:Int}""")
36+
typeCheck("""
37+
import zio.blocks.schema._
38+
sealed trait Result
39+
object Result {
40+
case class Success(value: Int) extends Result
41+
case class Failure(error: String) extends Result
42+
}
43+
val schema = Schema.derived[Result]
44+
val structural: Schema[{def Tag: "Failure"; def error: String} | {def Tag: "Success"; def value: Int}] = schema.structural
45+
""").map(result => assertTrue(result.isRight))
4046
},
4147
test("structural sealed trait schema is a Variant") {
4248
val schema = Schema.derived[Result]
@@ -57,10 +63,16 @@ object SealedTraitToUnionSpec extends ZIOSpecDefault {
5763
assertTrue(caseCount == 2)
5864
},
5965
test("sealed trait with case objects has exact structural type name") {
60-
val schema = Schema.derived[Status]
61-
val structural = schema.structural
62-
val typeName = structural.reflect.typeName.name
63-
assertTrue(typeName == """{Tag:"Active"}|{Tag:"Inactive"}""")
66+
typeCheck("""
67+
import zio.blocks.schema._
68+
sealed trait Status
69+
object Status {
70+
case object Active extends Status
71+
case object Inactive extends Status
72+
}
73+
val schema = Schema.derived[Status]
74+
val structural: Schema[{def Tag: "Active"} | {def Tag: "Inactive"}] = schema.structural
75+
""").map(result => assertTrue(result.isRight))
6476
},
6577
test("three variant sealed trait structural has all cases") {
6678
val schema = Schema.derived[Animal]

schema/jvm/src/test/scala-3/zio/blocks/schema/structural/StructuralRoundTripSpec.scala

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -109,35 +109,34 @@ object StructuralRoundTripSpec extends ZIOSpecDefault {
109109
)
110110
}
111111
),
112-
suite("Structural type name verification")(
113-
test("product structural type has correct field names in type name") {
114-
val schema = Schema.derived[Simple]
115-
val structural = schema.structural
116-
val typeName = structural.reflect.typeName.name
117-
assertTrue(
118-
typeName.contains("x:Int"),
119-
typeName.contains("y:String")
120-
)
112+
suite("Type-level structural conversion")(
113+
test("Simple product converts to structural type") {
114+
typeCheck("""
115+
import zio.blocks.schema._
116+
case class Simple(x: Int, y: String)
117+
val schema = Schema.derived[Simple]
118+
val structural: Schema[{def x: Int; def y: String}] = schema.structural
119+
""").map(result => assertTrue(result.isRight))
121120
},
122-
test("sum type structural has union type name with Tag") {
123-
val schema = Schema.derived[Animal]
124-
val structural = schema.structural
125-
val typeName = structural.reflect.typeName.name
126-
assertTrue(
127-
typeName.contains("Dog"),
128-
typeName.contains("Cat"),
129-
typeName.contains("Fish"),
130-
typeName.contains("|")
131-
)
121+
test("Animal sealed trait converts to union structural type") {
122+
typeCheck("""
123+
import zio.blocks.schema._
124+
sealed trait Animal
125+
case class Dog(name: String, breed: String) extends Animal
126+
case class Cat(name: String, indoor: Boolean) extends Animal
127+
case object Fish extends Animal
128+
val schema = Schema.derived[Animal]
129+
val structural: Schema[{def Tag: "Cat"; def indoor: Boolean; def name: String} | {def Tag: "Dog"; def breed: String; def name: String} | {def Tag: "Fish"}] = schema.structural
130+
""").map(result => assertTrue(result.isRight))
132131
},
133-
test("nested structural type has nested field type names") {
134-
val schema = Schema.derived[Nested]
135-
val structural = schema.structural
136-
val typeName = structural.reflect.typeName.name
137-
assertTrue(
138-
typeName.contains("inner:"),
139-
typeName.contains("flag:Boolean")
140-
)
132+
test("Nested product converts to structural type") {
133+
typeCheck("""
134+
import zio.blocks.schema._
135+
case class Simple(x: Int, y: String)
136+
case class Nested(inner: Simple, flag: Boolean)
137+
val schema = Schema.derived[Nested]
138+
val structural: Schema[{def flag: Boolean; def inner: Simple}] = schema.structural
139+
""").map(result => assertTrue(result.isRight))
141140
}
142141
),
143142
suite("Structural schema preserves reflect structure")(

0 commit comments

Comments
 (0)