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
8 changes: 3 additions & 5 deletions build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object Versions {
def graalVmVersion = "22.3.1"
def coursier = "2.1.25-M26"
def osLib = "0.11.8"
def uTest = "0.9.5"
def munit = "1.3.6"
def ubuntu = "24.04"
}

Expand Down Expand Up @@ -121,16 +121,14 @@ object `java-class-name` extends JavaClassNameModule with JavaMainClassNativeIma
}
}

trait Tests extends ScalaModule with TestModule.Utest {
trait Tests extends ScalaModule with TestModule.Munit {
def launcher: T[PathRef]

def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
mvn"com.lihaoyi::os-lib:${Versions.osLib}",
mvn"com.lihaoyi::utest:${Versions.uTest}"
mvn"org.scalameta::munit:${Versions.munit}"
)

def testFramework = "utest.runner.Framework"

def forkEnv: T[Map[String, String]] = super.forkEnv() ++ Seq(
"JAVA_CLASS_NAME_CLI" -> launcher().path.toString
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,168 @@
package cli.javaclassname

import utest.*

object JavaClassNameTests extends TestSuite {
class JavaClassNameTests extends munit.FunSuite {

val launcher = Option(System.getenv("JAVA_CLASS_NAME_CLI"))
.map(os.Path(_, os.pwd))
.getOrElse {
sys.error("JAVA_CLASS_NAME_CLI not set")
}

val tests = Tests {
test("simple") {
val expectedClassName = "Foo"
val content =
s"""package a.b.c;
|
|public class $expectedClassName {
| private int n = 2;
| public String getThing() {
| return "a";
| }
|}
|""".stripMargin
val tmpDir = os.temp.dir()
try {
os.write(tmpDir / "Foo.java", content)
val res = os.proc(launcher, "Foo.java")
.call(cwd = tmpDir)
val className = res.out.text().trim
assert(className == expectedClassName)
}
finally
os.remove.all(tmpDir)
private def extractClassName(fileName: String, content: String): String = {
val tmpDir = os.temp.dir()
try {
os.write(tmpDir / fileName, content)
val res = os.proc(launcher, fileName)
.call(cwd = tmpDir)
res.out.text().trim
}
finally
os.remove.all(tmpDir)
}

test("simple") {
val expectedClassName = "Foo"
val content =
s"""package a.b.c;
|
|public class $expectedClassName {
| private int n = 2;
| public String getThing() {
| return "a";
| }
|}
|""".stripMargin
assertEquals(extractClassName("Foo.java", content), expectedClassName)
}

test("no package") {
val content =
"""public class NoPackage {}
|""".stripMargin
assertEquals(extractClassName("NoPackage.java", content), "NoPackage")
}

test("generic class") {
val content =
"""package a;
|
|import java.util.*;
|
|public class Generic<T extends Comparable<T>, U> extends ArrayList<T> implements Map.Entry<T, U> {
| public T getKey() { return null; }
| public U getValue() { return null; }
| public U setValue(U u) { return u; }
|}
|""".stripMargin
assertEquals(extractClassName("Generic.java", content), "Generic")
}

test("void methods") {
val content =
"""package a;
|
|public class VoidMethods {
| private int n = 2;
| public void run() {}
| public static void main(String[] args) {}
| void g(int x, long y) {}
|}
|""".stripMargin
assertEquals(extractClassName("VoidMethods.java", content), "VoidMethods")
}

test("interface") {
val content =
"""package a;
|
|public interface Iface<T> {
| void f();
| default int g() { return 1; }
|}
|""".stripMargin
assertEquals(extractClassName("Iface.java", content), "Iface")
}

test("annotation") {
val content =
"""package a;
|
|public @interface Annot {
| String value() default "";
| int n() default 0;
|}
|""".stripMargin
assertEquals(extractClassName("Annot.java", content), "Annot")
}

test("record with reference components") {
val content =
"""package a;
|
|public record RefRecord(String a, Object b) {}
|""".stripMargin
assertEquals(extractClassName("RefRecord.java", content), "RefRecord")
}

// TODO: primitive types need initialized compiler definitions, the launcher crashes with an NPE
// https://github.com/VirtusLab/scala-cli/issues/4516
test("record with primitive components".ignore) {
val content =
"""package a;
|
|public record PrimRecord(int a, String b) {}
|""".stripMargin
assertEquals(extractClassName("PrimRecord.java", content), "PrimRecord")
}

// TODO: enums need initialized compiler definitions, the launcher crashes with an NPE
// https://github.com/VirtusLab/scala-cli/issues/4514
test("enum".ignore) {
val content =
"""package a;
|
|public enum SimpleEnum { A, B }
|""".stripMargin
assertEquals(extractClassName("SimpleEnum.java", content), "SimpleEnum")
}

// TODO: enums need initialized compiler definitions, the launcher crashes with an NPE
// https://github.com/VirtusLab/scala-cli/issues/4514
test("enum with methods".ignore) {
val content =
"""package a;
|
|public enum MethodEnum {
| A, B;
| void f() {}
| int g() { return 1; }
|}
|""".stripMargin
assertEquals(extractClassName("MethodEnum.java", content), "MethodEnum")
}

// TODO: package-private classes aren't filtered out, "PackagePrivate" is printed
// https://github.com/VirtusLab/scala-cli/issues/4515
test("package-private class".ignore) {
val content =
"""package a;
|
|class PackagePrivate {}
|""".stripMargin
assertEquals(extractClassName("PackagePrivate.java", content), "")
}

// TODO: package-private classes aren't filtered out, "Helper" is printed
// https://github.com/VirtusLab/scala-cli/issues/4515
test("public class after a package-private one".ignore) {
val content =
"""package a;
|
|class Helper {}
|
|public class Second {}
|""".stripMargin
assertEquals(extractClassName("Second.java", content), "Second")
}

}
Loading