Skip to content

Commit 8f16d9e

Browse files
committed
Add infrastructure to run the JUnit tests of upstream Scala.js.
And run one test for now: `compiler/IntTest.scala`.
1 parent 94b1da7 commit 8f16d9e

File tree

4 files changed

+176
-24
lines changed

4 files changed

+176
-24
lines changed

.drone.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pipeline:
3131
image: lampepfl/dotty:2019-04-22
3232
commands:
3333
- cp -R . /tmp/2/ && cd /tmp/2/
34-
- ./project/scripts/sbt ";dotty-bootstrapped/compile ;dotty-bootstrapped/test; dotty-semanticdb/compile; dotty-semanticdb/test:compile;sjsSandbox/run;sjsSandbox/test"
34+
- ./project/scripts/sbt ";dotty-bootstrapped/compile ;dotty-bootstrapped/test; dotty-semanticdb/compile; dotty-semanticdb/test:compile;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test"
3535
- ./project/scripts/bootstrapCmdTests
3636

3737
community_build:

build.sbt

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ val `dotty-compiler` = Build.`dotty-compiler`
77
val `dotty-compiler-bootstrapped` = Build.`dotty-compiler-bootstrapped`
88
val `dotty-library` = Build.`dotty-library`
99
val `dotty-library-bootstrapped` = Build.`dotty-library-bootstrapped`
10+
val `dotty-library-bootstrappedJS` = Build.`dotty-library-bootstrappedJS`
1011
val `dotty-sbt-bridge` = Build.`dotty-sbt-bridge`
1112
val `dotty-sbt-bridge-tests` = Build.`dotty-sbt-bridge-tests`
1213
val `dotty-language-server` = Build.`dotty-language-server`
@@ -23,6 +24,7 @@ val `dist-bootstrapped` = Build.`dist-bootstrapped`
2324
val `community-build` = Build.`community-build`
2425

2526
val sjsSandbox = Build.sjsSandbox
27+
val sjsJUnitTests = Build.sjsJUnitTests
2628

2729
val `sbt-dotty` = Build.`sbt-dotty`
2830
val `vscode-dotty` = Build.`vscode-dotty`

project/Build.scala

+129-23
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,35 @@ import sbtbuildinfo.BuildInfoPlugin.autoImport._
2828

2929
import scala.util.Properties.isJavaAtLeast
3030

31+
object MyScalaJSPlugin extends AutoPlugin {
32+
import Build._
33+
34+
override def requires: Plugins = ScalaJSPlugin
35+
36+
override def projectSettings: Seq[Setting[_]] = Def.settings(
37+
commonBootstrappedSettings,
38+
39+
/* Remove the Scala.js compiler plugin for scalac, and enable the
40+
* Scala.js back-end of dotty instead.
41+
*/
42+
libraryDependencies := {
43+
val deps = libraryDependencies.value
44+
deps.filterNot(_.name.startsWith("scalajs-compiler")).map(_.withDottyCompat(scalaVersion.value))
45+
},
46+
scalacOptions += "-scalajs",
47+
48+
// Replace the JVM JUnit dependency by the Scala.js one
49+
libraryDependencies ~= {
50+
_.filter(!_.name.startsWith("junit-interface"))
51+
},
52+
libraryDependencies +=
53+
"org.scala-js" % "scalajs-junit-test-runtime_2.12" % scalaJSVersion % "test",
54+
55+
// Typecheck the Scala.js IR found on the classpath
56+
scalaJSLinkerConfig ~= (_.withCheckIR(true)),
57+
)
58+
}
59+
3160
object Build {
3261
val scalacVersion = "2.12.8"
3362
val referenceVersion = "0.14.0-RC1"
@@ -101,6 +130,8 @@ object Build {
101130
val ideTestsCompilerArguments = taskKey[Seq[String]]("Compiler arguments to use in IDE tests")
102131
val ideTestsDependencyClasspath = taskKey[Seq[File]]("Dependency classpath to use in IDE tests")
103132

133+
val fetchScalaJSSource = taskKey[File]("Fetch the sources of Scala.js")
134+
104135
lazy val SourceDeps = config("sourcedeps")
105136

106137
// Settings shared by the build (scoped in ThisBuild). Used in build.sbt
@@ -714,6 +745,22 @@ object Build {
714745
case Bootstrapped => `dotty-library-bootstrapped`
715746
}
716747

748+
lazy val `dotty-library-bootstrappedJS`: Project = project.in(file("library-js")).
749+
asDottyLibrary(Bootstrapped).
750+
enablePlugins(MyScalaJSPlugin).
751+
settings(
752+
// TODO Compile more (enventually all) of the library
753+
/*unmanagedSourceDirectories in Compile :=
754+
(unmanagedSourceDirectories in (`dotty-library-bootstrapped`, Compile)).value,*/
755+
sources in Compile := {
756+
val baseDir = (baseDirectory in (`dotty-library-bootstrapped`, Compile)).value
757+
Seq(
758+
baseDir / "src/scala/forceInline.scala",
759+
baseDir / "src-3.x/dotty/DottyPredef.scala",
760+
)
761+
},
762+
)
763+
717764
lazy val `dotty-sbt-bridge` = project.in(file("sbt-bridge/src")).
718765
// We cannot depend on any bootstrapped project to compile the bridge, since the
719766
// bridge is needed to compile these projects.
@@ -819,36 +866,95 @@ object Build {
819866
* useful, as that would not provide the linker and JS runners.
820867
*/
821868
lazy val sjsSandbox = project.in(file("sandbox/scalajs")).
822-
enablePlugins(ScalaJSPlugin).
823-
dependsOn(dottyLibrary(Bootstrapped)).
824-
settings(commonBootstrappedSettings).
869+
enablePlugins(MyScalaJSPlugin).
870+
dependsOn(`dotty-library-bootstrappedJS`).
825871
settings(
826-
/* Remove the Scala.js compiler plugin for scalac, and enable the
827-
* Scala.js back-end of dotty instead.
828-
*/
829-
libraryDependencies := {
830-
val deps = libraryDependencies.value
831-
deps.filterNot(_.name.startsWith("scalajs-compiler")).map(_.withDottyCompat(scalaVersion.value))
832-
},
833-
scalacOptions += "-scalajs",
872+
scalaJSUseMainModuleInitializer := true,
873+
)
834874

835-
// Replace the JVM JUnit dependency by the Scala.js one
836-
libraryDependencies ~= {
837-
_.filter(!_.name.startsWith("junit-interface"))
875+
lazy val sjsJUnitTests = project.in(file("tests/sjs-junit")).
876+
enablePlugins(MyScalaJSPlugin).
877+
dependsOn(`dotty-library-bootstrappedJS`).
878+
settings(
879+
scalacOptions --= Seq("-Xfatal-warnings", "-deprecation"),
880+
881+
sourceDirectory in fetchScalaJSSource := target.value / s"scala-js-src-$scalaJSVersion",
882+
883+
fetchScalaJSSource := {
884+
import org.eclipse.jgit.api._
885+
886+
val s = streams.value
887+
val ver = scalaJSVersion
888+
val trgDir = (sourceDirectory in fetchScalaJSSource).value
889+
890+
if (!trgDir.exists) {
891+
s.log.info(s"Fetching Scala.js source version $ver")
892+
IO.createDirectory(trgDir)
893+
new CloneCommand()
894+
.setDirectory(trgDir)
895+
.setURI("https://github.com/scala-js/scala-js.git")
896+
.call()
897+
}
898+
899+
// Checkout proper ref. We do this anyway so we fail if something is wrong
900+
val git = Git.open(trgDir)
901+
s.log.info(s"Checking out Scala.js source version $ver")
902+
git.checkout().setName(s"v$ver").call()
903+
904+
trgDir
838905
},
906+
907+
// We need JUnit in the Compile configuration
839908
libraryDependencies +=
840-
"org.scala-js" % "scalajs-junit-test-runtime_2.12" % scalaJSVersion % "test",
909+
"org.scala-js" % "scalajs-junit-test-runtime_2.12" % scalaJSVersion,
910+
911+
sourceGenerators in Compile += Def.task {
912+
import org.scalajs.linker.CheckedBehavior
841913

842-
// The main class cannot be found automatically due to the empty inc.Analysis
843-
mainClass in Compile := Some("hello.HelloWorld"),
914+
val stage = scalaJSStage.value
844915

845-
scalaJSUseMainModuleInitializer := true,
916+
val linkerConfig = stage match {
917+
case FastOptStage => (scalaJSLinkerConfig in (Compile, fastOptJS)).value
918+
case FullOptStage => (scalaJSLinkerConfig in (Compile, fullOptJS)).value
919+
}
846920

847-
/* Debug-friendly Scala.js optimizer options.
848-
* In particular, typecheck the Scala.js IR found on the classpath.
849-
*/
850-
scalaJSLinkerConfig ~= {
851-
_.withCheckIR(true).withParallel(false)
921+
val moduleKind = linkerConfig.moduleKind
922+
val sems = linkerConfig.semantics
923+
924+
ConstantHolderGenerator.generate(
925+
(sourceManaged in Compile).value,
926+
"org.scalajs.testsuite.utils.BuildInfo",
927+
"scalaVersion" -> scalaVersion.value,
928+
"hasSourceMaps" -> false, //MyScalaJSPlugin.wantSourceMaps.value,
929+
"isNoModule" -> (moduleKind == ModuleKind.NoModule),
930+
"isESModule" -> (moduleKind == ModuleKind.ESModule),
931+
"isCommonJSModule" -> (moduleKind == ModuleKind.CommonJSModule),
932+
"isFullOpt" -> (stage == FullOptStage),
933+
"compliantAsInstanceOfs" -> (sems.asInstanceOfs == CheckedBehavior.Compliant),
934+
"compliantArrayIndexOutOfBounds" -> (sems.arrayIndexOutOfBounds == CheckedBehavior.Compliant),
935+
"compliantModuleInit" -> (sems.moduleInit == CheckedBehavior.Compliant),
936+
"strictFloats" -> sems.strictFloats,
937+
"productionMode" -> sems.productionMode,
938+
"es2015" -> linkerConfig.esFeatures.useECMAScript2015,
939+
)
940+
}.taskValue,
941+
942+
managedSources in Compile ++= {
943+
val dir = fetchScalaJSSource.value / "test-suite/js/src/main/scala"
944+
val filter = (
945+
("*.scala": FileFilter)
946+
-- "Typechecking*.scala"
947+
-- "NonNativeTypeTestSeparateRun.scala"
948+
)
949+
(dir ** filter).get
950+
},
951+
952+
managedSources in Test ++= {
953+
val dir = fetchScalaJSSource.value / "test-suite"
954+
(
955+
(dir / "shared/src/test/scala/org/scalajs/testsuite/compiler" ** "IntTest.scala").get
956+
++ (dir / "shared/src/test/scala/org/scalajs/testsuite/utils" ** "*.scala").get
957+
)
852958
}
853959
)
854960

project/ConstantHolderGenerator.scala

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import scala.annotation.tailrec
2+
3+
import sbt._
4+
5+
import org.scalajs.ir.ScalaJSVersions
6+
7+
object ConstantHolderGenerator {
8+
/** Generate a *.scala file that contains the given values as literals. */
9+
def generate(dir: File, fqn: String, values: (String, Any)*): Seq[File] = {
10+
val (fullPkg@(_ :+ pkg)) :+ objectName = fqn.split('.').toSeq
11+
12+
val out = dir / (objectName + ".scala")
13+
14+
val defs = for {
15+
(name, value) <- values
16+
} yield {
17+
s"val $name = ${literal(value)}"
18+
}
19+
20+
val scalaCode =
21+
s"""
22+
package ${fullPkg.mkString(".")}
23+
24+
private[$pkg] object $objectName {
25+
${defs.mkString("\n")}
26+
}
27+
"""
28+
29+
IO.write(out, scalaCode)
30+
31+
Seq(out)
32+
}
33+
34+
@tailrec
35+
private final def literal(v: Any): String = v match {
36+
case s: String => "raw\"\"\"" + s + "\"\"\""
37+
case b: Boolean => b.toString
38+
case f: File => literal(f.getAbsolutePath)
39+
40+
case _ =>
41+
throw new IllegalArgumentException(
42+
"Unsupported value type: " + v.getClass)
43+
}
44+
}

0 commit comments

Comments
 (0)