Skip to content

Commit

Permalink
surface (feature): Scala Native support (#3501)
Browse files Browse the repository at this point in the history
- Almost no change was required to support Scala Native 
- internal: Remove dependency to munit
  • Loading branch information
xerial authored Apr 23, 2024
1 parent 3c05c5e commit d960bdc
Show file tree
Hide file tree
Showing 22 changed files with 96 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package wvlet.airframe.surface

class AbstractTypeTest extends munit.FunSuite {
import wvlet.airspec.AirSpec

class AbstractTypeTest extends AirSpec {

trait Abst {
def hello = "hello abst"
Expand All @@ -14,6 +16,6 @@ class AbstractTypeTest extends munit.FunSuite {
assert(s.objectFactory.isDefined)

val a = s.objectFactory.get.newInstance(Seq.empty).asInstanceOf[Abst]
assertEquals(a.hello, "hello impl")
a.hello shouldBe "hello impl"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@
*/
package wvlet.airframe.surface

import wvlet.airspec.AirSpec

/**
*/
class InnerClassTest extends munit.FunSuite {
class InnerClassTest extends AirSpec {
case class A(id: Int, name: String)

test("pass inner class context to Surface") {
val s = Surface.of[A]
val a = s.objectFactory.map { x => x.newInstance(Seq(1, "leo")) }
assertEquals(a, Some(A(1, "leo")))
a shouldBe Some(A(1, "leo"))
}

test("find an inner class inside a code block") {
new {
val s = Surface.of[A]
val a = s.objectFactory.map { x => x.newInstance(Seq(1, "leo")) }
assertEquals(a, Some(A(1, "leo")))
a shouldBe Some(A(1, "leo"))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ package wvlet.airframe.surface.reflect

import scala.language.higherKinds
import wvlet.airframe.surface.Surface
import wvlet.airspec.AirSpec

/**
*/
class NamedParameterTest extends munit.FunSuite {
class NamedParameterTest extends AirSpec {

trait MyService[F[_]] {
def hello: F[String]
Expand All @@ -28,13 +29,13 @@ class NamedParameterTest extends munit.FunSuite {

test("read F[_]") {
val s = Surface.of[MyService[A]]
assertEquals(s.toString, "MyService[A]")
s.toString shouldBe "MyService[A]"

val m = Surface.methodsOf[MyService[A]]
assert(m.headOption.isDefined)

val m1 = m.head
// info(m1.returnType.getClass())
assertEquals(m1.returnType.toString, "F[String]")
m1.returnType.toString shouldBe "F[String]"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ class RuntimeSurfaceTest extends SurfaceSpec {

test("resolve trait type") {
val s = RuntimeSurface.of[TraitOnly]
assertEquals(s.isAlias, false)
s.isAlias shouldBe false
assert(s.rawType == classOf[TraitOnly])

val m = Surface.methodsOf[TraitOnly].head
assertEquals(m.owner.isAlias, false)
m.owner.isAlias shouldBe false
assert(m.owner.rawType == classOf[TraitOnly])

assert(m.findAnnotationOf[secret].isDefined)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import java.util.concurrent.ConcurrentHashMap
import scala.collection.mutable
import scala.jdk.CollectionConverters.*


val surfaceCache = new ConcurrentHashMap[String, Surface]().asScala
val methodSurfaceCache = new ConcurrentHashMap[String, Seq[MethodSurface]]().asScala

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
package wvlet.airframe.surface

import wvlet.log.LogSupport
import wvlet.airspec.AirSpec

/**
*/
class AliasSurfaceTest extends munit.FunSuite with LogSupport {
class AliasSurfaceTest extends AirSpec {

case class Holder[A](v: A)
type MyInt = Holder[Int]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
*/
package wvlet.airframe.surface

class CNameTest extends munit.FunSuite {
import wvlet.airspec.AirSpec

class CNameTest extends AirSpec {
test("convert to snakeCase") {
assert(CName("AirframeSurface").snakeCase == "airframe_surface")
assert(CName("airframe_surface").snakeCase == "airframe_surface")
Expand Down Expand Up @@ -48,16 +50,16 @@ class CNameTest extends munit.FunSuite {

test("null values") {
val nullName = CName(null)
assertEquals(nullName.canonicalName, "")
assertEquals(nullName.naturalName, "")
nullName.canonicalName shouldBe ""
nullName.naturalName shouldBe ""
}

test("comparison") {
val a = CName("Apple")
val b = CName("Banana")
assertEquals(a.compareTo(b) < 0, true)
assertEquals(a, a)
assertNotEquals(a, b)
assertNotEquals(a.hashCode, b.hashCode)
a.compareTo(b) < 0 shouldBe true
a shouldBe a
a shouldNotBe b
a.hashCode shouldNotBe b.hashCode
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*/
package wvlet.airframe.surface

import wvlet.airspec.AirSpec

/**
*/
object EnumTest {
Expand All @@ -29,16 +31,16 @@ object EnumTest {
}
}

class EnumTest extends munit.FunSuite {
class EnumTest extends AirSpec {
import EnumTest.*

test("Find Surface.stringExtractor") {
Surface.of[Color] match {
case s: EnumSurface =>
val f = s.stringExtractor
assertEquals(f(classOf[Color], "Blue"), Some(Blue))
assertEquals(f(classOf[Color], "Red"), Some(Red))
assertEquals(f(classOf[Color], "White"), None)
f(classOf[Color], "Blue") shouldBe Some(Blue)
f(classOf[Color], "Red") shouldBe Some(Red)
f(classOf[Color], "White") shouldBe None
case other =>
fail(s"EnumSurface should be used: ${other.getClass}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ class MethodSurfaceTest extends SurfaceSpec {
val v = h.getMethodArgDefaultValue(d)
if (!isScalaJS) {
// Scala.js doesn't support reading default method arguments
assertEquals(v, Some("hello"))
v shouldBe Some("hello")
}

val msg = m.call(d, "world")
assertEquals(msg, "world")
msg shouldBe "world"
}

test("find method default parameter in trait") {
Expand All @@ -127,15 +127,15 @@ class MethodSurfaceTest extends SurfaceSpec {
assert(m.args.headOption.isDefined)
val h = m.args.head
// FIXME: Fix StaticMethodParameter in CompileTimeSurfaceFactory for Scala 3
if (!isScalaJS && !isScala3JVM) {
assertEquals(h.getDefaultValue, Some("default"))
if (!isScalaJS && !isScalaNative && !(isScala3 && isScalaJVM)) {
h.getDefaultValue shouldBe Some("default")

val d = new E {
override def hello(v: String = "yay"): String = v
}
val v = h.getMethodArgDefaultValue(d)
// Scala.js doesn't support reading default method arguments
assertEquals(v, Some("yay"))
v shouldBe Some("yay")
}
}

Expand All @@ -145,7 +145,7 @@ class MethodSurfaceTest extends SurfaceSpec {
case Some(m) if m.args.size == 1 =>
val arg = m.args(0)
val p1 = arg.surface.typeArgs(1)
assertEquals(p1.fullName, "scala.Any")
p1.fullName shouldBe "scala.Any"
case _ =>
fail("F.mapInput method not found")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@ class ParamTest extends SurfaceSpec {
val s = Surface.of[ParamTest.B]
val p1 = s.params(0)
val v = ParamTest.B(1, 2, 3)
assertEquals(p1.get(v), 1)
p1.get(v) shouldBe 1
}

test("access params through alias") {
val s = Surface.of[ParamTest.A1]
val p1 = s.params(0)
val p2 = s.params(1)
val v: ParamTest.A1 = ParamTest.A(10, 20)
assertEquals(p1.get(v), 10)
assertEquals(p2.get(v), 20)
p1.get(v) shouldBe 10
p2.get(v) shouldBe 20
}

test("private field access") {
Expand All @@ -62,8 +62,8 @@ class ParamTest extends SurfaceSpec {
val p2 = s.params(1)
val p3 = s.params(2)
val v = ParamTest.B(1, 2, 3)
assertEquals(p1.get(v), 1)
assertEquals(p2.get(v), 2)
assertEquals(p3.get(v), 3)
p1.get(v) shouldBe 1
p2.get(v) shouldBe 2
p3.get(v) shouldBe 3
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ class QuoteParamTest extends SurfaceSpec {
val s = Surface.of[QP]
val obj = QP("A")
val p = s.params.head
assertEquals(p.get(obj), obj.`system-+=type`)
p.get(obj) shouldBe obj.`system-+=type`
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
* limitations under the License.
*/
package wvlet.airframe.surface
import wvlet.airspec.AirSpec

class RecordSurfaceTest extends munit.FunSuite {
class RecordSurfaceTest extends AirSpec {
test("build custom surface") {
val p1 = RecordParameter(0, "p1", Primitive.Int)
val p2 = RecordParameter(1, "p2", Primitive.String)
Expand All @@ -24,10 +25,10 @@ class RecordSurfaceTest extends munit.FunSuite {
.addParam(p2)
.addParam(p3)

assertEquals(s.typeArgs, Seq.empty)
assertEquals(s.params.length, 3)
assertEquals(s.params(0), p1)
assertEquals(s.params(1), p2)
assertEquals(s.params(2), p3)
s.typeArgs shouldBe Seq.empty
s.params.length shouldBe 3
s.params(0) shouldBe p1
s.params(1) shouldBe p2
s.params(2) shouldBe p3
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class RecursiveHigherKindTypeTest extends SurfaceSpec {

test("support recursive higher kind types") {
val s = Surface.of[Holder[BySkinny]]
assertEquals(s.name, "Holder[BySkinny]")
assertEquals(s.isAlias, false)
assertEquals(s.isPrimitive, false)
assertEquals(s.isOption, false)
assertEquals(s.dealias.toString, "Holder[BySkinny]")

assertEquals(s.typeArgs(0).name, "BySkinny")
assertEquals(s.typeArgs(0).dealias.name, "MyTask[A]")
s.name shouldBe "Holder[BySkinny]"
s.isAlias shouldBe false
s.isPrimitive shouldBe false
s.isOption shouldBe false
s.dealias.toString shouldBe "Holder[BySkinny]"

s.typeArgs(0).name shouldBe "BySkinny"
s.typeArgs(0).dealias.name shouldBe "MyTask[A]"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* limitations under the License.
*/
package wvlet.airframe.surface
import wvlet.airspec.AirSpec

object RecursiveMethodParamTest {
case class Node(parent: Option[Node])
Expand All @@ -21,7 +22,7 @@ object RecursiveMethodParamTest {
}
}

class RecursiveMethodParamTest extends munit.FunSuite {
class RecursiveMethodParamTest extends AirSpec {
import RecursiveMethodParamTest.*

// ....
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ class RecursiveSurfaceTest extends SurfaceSpec {
test("support generic recursive type") {
val c: Surface = Surface.of[TypedCons[String]]
debug(s"TypeCons[String] ${c.getClass}")
assertEquals(c.toString, "TypedCons[String]")
c.toString shouldBe "TypedCons[String]"

assertEquals(c.params.length, 2)
assertEquals(c.params(0).surface, Primitive.Int)
c.params.length shouldBe 2
c.params(0).surface shouldBe Primitive.Int

val lazyC: Surface = c.params(1).surface
debug(s"lazyC surface: ${lazyC.getClass}...")
assertEquals(lazyC.toString, "TypedCons[String]")
assertEquals(lazyC.params.length, 2)
assertEquals(lazyC.isPrimitive, false)
assertEquals(lazyC.isOption, false)
lazyC.toString shouldBe "TypedCons[String]"
lazyC.params.length shouldBe 2
lazyC.isPrimitive shouldBe false
lazyC.isOption shouldBe false
}
}
Loading

0 comments on commit d960bdc

Please sign in to comment.