diff --git a/bench/src/main/scala/sjsonnet/MainBenchmark.scala b/bench/src/main/scala/sjsonnet/MainBenchmark.scala index ed50b875b..e42d922c5 100644 --- a/bench/src/main/scala/sjsonnet/MainBenchmark.scala +++ b/bench/src/main/scala/sjsonnet/MainBenchmark.scala @@ -33,7 +33,7 @@ object MainBenchmark { Map.empty[String, String], Map.empty[String, String], OsPath(wd), - importer = SjsonnetMain + importer = SjsonnetMainBase .resolveImport(config.getOrderedJpaths.map(os.Path(_, wd)).map(OsPath(_)), None), parseCache = parseCache ) @@ -65,7 +65,7 @@ class MainBenchmark { @Benchmark def main(bh: Blackhole): Unit = { bh.consume( - SjsonnetMain.main0( + SjsonnetMainBase.main0( MainBenchmark.mainArgs, new DefaultParseCache, System.in, @@ -102,7 +102,7 @@ object MemoryBenchmark { } else { false } - SjsonnetMain.main0( + SjsonnetMainBase.main0( MainBenchmark.mainArgs, cache, System.in, diff --git a/bench/src/main/scala/sjsonnet/MaterializerBenchmark.scala b/bench/src/main/scala/sjsonnet/MaterializerBenchmark.scala index 76ed60a1d..bce790216 100644 --- a/bench/src/main/scala/sjsonnet/MaterializerBenchmark.scala +++ b/bench/src/main/scala/sjsonnet/MaterializerBenchmark.scala @@ -32,7 +32,7 @@ class MaterializerBenchmark { Map.empty[String, String], Map.empty[String, String], OsPath(wd), - importer = SjsonnetMain + importer = SjsonnetMainBase .resolveImport( config.getOrderedJpaths.map(os.Path(_, wd)).map(OsPath(_)).toIndexedSeq, None diff --git a/bench/src/main/scala/sjsonnet/MultiThreadedBenchmark.scala b/bench/src/main/scala/sjsonnet/MultiThreadedBenchmark.scala index 004411686..a4f50b08b 100644 --- a/bench/src/main/scala/sjsonnet/MultiThreadedBenchmark.scala +++ b/bench/src/main/scala/sjsonnet/MultiThreadedBenchmark.scala @@ -39,7 +39,7 @@ class MultiThreadedBenchmark { pool.submit { (() => if ( - SjsonnetMain.main0( + SjsonnetMainBase.main0( MainBenchmark.mainArgs, cache, // new DefaultParseCache System.in, diff --git a/bench/src/main/scala/sjsonnet/RunProfiler.scala b/bench/src/main/scala/sjsonnet/RunProfiler.scala index b2ec0281c..c183c315a 100644 --- a/bench/src/main/scala/sjsonnet/RunProfiler.scala +++ b/bench/src/main/scala/sjsonnet/RunProfiler.scala @@ -15,7 +15,7 @@ object RunProfiler extends App { Map.empty[String, String], Map.empty[String, String], OsPath(wd), - importer = SjsonnetMain + importer = SjsonnetMainBase .resolveImport(config.getOrderedJpaths.map(os.Path(_, wd)).map(OsPath(_)).toIndexedSeq, None), parseCache = parseCache ) { diff --git a/build.mill b/build.mill index 66697d557..c64d5d0e7 100644 --- a/build.mill +++ b/build.mill @@ -102,7 +102,8 @@ object sjsonnet extends VersionFileModule { def jsEnvConfig = JsEnvConfig.NodeJs(args = List("--stack-size=" + stackSizekBytes)) def resources = T.sources( this.millSourcePath / "resources" / "test_suite", - this.millSourcePath / "resources" / "go_test_suite" + this.millSourcePath / "resources" / "go_test_suite", + this.millSourcePath / "resources" / "new_test_suite", ) def generatedSources = T { resources().map(_.path).flatMap { testSuite => diff --git a/sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala b/sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala index 4b6c58350..5914218f2 100644 --- a/sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala +++ b/sjsonnet/server/src/sjsonnet/SjsonnetServerMain.scala @@ -80,7 +80,7 @@ object SjsonnetServerMain extends SjsonnetServerMain[DefaultParseCache] { scala.Console.withIn(stdin) { scala.Console.withOut(stdout) { scala.Console.withErr(stderr) { - sjsonnet.SjsonnetMain.main0(args, stateCache2, stdin, stdout, stderr, wd) == 0 + sjsonnet.SjsonnetMainBase.main0(args, stateCache2, stdin, stdout, stderr, wd) == 0 } } } diff --git a/sjsonnet/src-js/sjsonnet/Platform.scala b/sjsonnet/src-js/sjsonnet/Platform.scala index dc523bb97..fb9a8d19f 100644 --- a/sjsonnet/src-js/sjsonnet/Platform.scala +++ b/sjsonnet/src-js/sjsonnet/Platform.scala @@ -2,25 +2,11 @@ package sjsonnet import org.virtuslab.yaml.* -import java.io.File import java.util import java.util.regex.Pattern import scala.collection.mutable object Platform { - def gzipBytes(s: Array[Byte]): String = { - throw new Exception("GZip not implemented in Scala.js") - } - def gzipString(s: String): String = { - throw new Exception("GZip not implemented in Scala.js") - } - def xzBytes(s: Array[Byte], compressionLevel: Option[Int]): String = { - throw new Exception("XZ not implemented in Scala.js") - } - def xzString(s: String, compressionLevel: Option[Int]): String = { - throw new Exception("XZ not implemented in Scala.js") - } - private def nodeToJson(node: Node): ujson.Value = node match { case _: Node.ScalarNode => YamlDecoder.forAny.construct(node).getOrElse("") match { @@ -98,9 +84,6 @@ object Platform { def sha3(s: String): String = { throw new Exception("SHA3 not implemented in Scala.js") } - def hashFile(file: File): String = { - throw new Exception("hashFile not implemented in Scala.js") - } private val regexCache = new util.concurrent.ConcurrentHashMap[String, Pattern] private val namedGroupPattern = Pattern.compile("\\(\\?<(.+?)>.*?\\)") diff --git a/sjsonnet/src-js/sjsonnet/SjsonnetMain.scala b/sjsonnet/src-js/sjsonnet/SjsonnetMain.scala index 9b92540e5..c9a449ba0 100644 --- a/sjsonnet/src-js/sjsonnet/SjsonnetMain.scala +++ b/sjsonnet/src-js/sjsonnet/SjsonnetMain.scala @@ -1,5 +1,7 @@ package sjsonnet +import sjsonnet.stdlib.NativeRegex + import scala.collection.mutable import scala.scalajs.js import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel} @@ -39,7 +41,8 @@ object SjsonnetMain { } }, parseCache = new DefaultParseCache, - new Settings(preserveOrder = preserveOrder) + settings = new Settings(preserveOrder = preserveOrder), + std = new Std(nativeFunctions = Map.from(new NativeRegex().functions)).Std ) interp.interpret0(text, JsVirtualPath("(memory)"), ujson.WebJson.Builder) match { case Left(msg) => throw new js.JavaScriptException(msg) diff --git a/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala b/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMainBase.scala similarity index 98% rename from sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala rename to sjsonnet/src-jvm-native/sjsonnet/SjsonnetMainBase.scala index 57420241b..2deee39c7 100644 --- a/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMain.scala +++ b/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMainBase.scala @@ -13,7 +13,7 @@ import java.nio.file.NoSuchFileException import scala.annotation.unused import scala.util.Try -object SjsonnetMain { +object SjsonnetMainBase { def resolveImport( searchRoots0: Seq[Path], // Evaluated in order, first occurrence wins allowedInputs: Option[Set[os.Path]] = None, @@ -60,19 +60,6 @@ object SjsonnetMain { } } - def main(args: Array[String]): Unit = { - val exitCode = main0( - args, - new DefaultParseCache, - System.in, - System.out, - System.err, - os.pwd, - None - ) - System.exit(exitCode) - } - def main0( args: Array[String], parseCache: ParseCache, diff --git a/sjsonnet/src-jvm-native/sjsonnet/stdlib/NativeGzip.scala b/sjsonnet/src-jvm-native/sjsonnet/stdlib/NativeGzip.scala new file mode 100644 index 000000000..2e1797e79 --- /dev/null +++ b/sjsonnet/src-jvm-native/sjsonnet/stdlib/NativeGzip.scala @@ -0,0 +1,19 @@ +package sjsonnet.stdlib + +import sjsonnet.functions.AbstractFunctionModule +import sjsonnet.{Error, EvalScope, Lazy, Platform, Position, Val} + +class NativeGzip extends AbstractFunctionModule { + def name = "gzip" + + val functions: Seq[(String, Val.Builtin)] = Seq( + "gzip" -> new Val.Builtin1("gzip", "v") { + override def evalRhs(v: Lazy, ev: EvalScope, pos: Position): Val = v.force match { + case Val.Str(_, value) => Val.Str(pos, Platform.gzipString(value)) + case arr: Val.Arr => + Val.Str(pos, Platform.gzipBytes(arr.iterator.map(_.cast[Val.Num].asInt.toByte).toArray)) + case x => Error.fail("Cannot gzip encode " + x.prettyName) + } + } + ) +} diff --git a/sjsonnet/src-jvm/sjsonnet/SjsonnetMain.scala b/sjsonnet/src-jvm/sjsonnet/SjsonnetMain.scala new file mode 100644 index 000000000..5f6ffd320 --- /dev/null +++ b/sjsonnet/src-jvm/sjsonnet/SjsonnetMain.scala @@ -0,0 +1,21 @@ +package sjsonnet + +import sjsonnet.stdlib.{NativeGzip, NativeRegex, NativeXz} + +object SjsonnetMain { + def main(args: Array[String]): Unit = { + val exitCode = SjsonnetMainBase.main0( + args, + new DefaultParseCache, + System.in, + System.out, + System.err, + os.pwd, + None, + std = new Std(nativeFunctions = + Map() ++ new NativeXz().functions ++ new NativeGzip().functions ++ new NativeRegex().functions + ).Std + ) + System.exit(exitCode) + } +} diff --git a/sjsonnet/src-jvm/sjsonnet/stdlib/NativeXz.scala b/sjsonnet/src-jvm/sjsonnet/stdlib/NativeXz.scala new file mode 100644 index 000000000..6f1c10a77 --- /dev/null +++ b/sjsonnet/src-jvm/sjsonnet/stdlib/NativeXz.scala @@ -0,0 +1,43 @@ +package sjsonnet.stdlib + +import sjsonnet.functions.AbstractFunctionModule +import sjsonnet.{Error, EvalScope, Lazy, Platform, Position, Val} + +class NativeXz extends AbstractFunctionModule { + def name = "xz" + + private val dummyPos: Position = new Position(null, 0) + + val functions: Seq[(String, Val.Builtin)] = Seq( + "xz" -> new Val.Builtin2( + "xz", + "v", + "compressionLevel", + Array(Val.Null(dummyPos), Val.Null(dummyPos)) + ) { + override def evalRhs(arg1: Lazy, arg2: Lazy, ev: EvalScope, pos: Position): Val = { + val compressionLevel: Option[Int] = arg2.force match { + case Val.Null(_) => + // Use default compression level if the user didn't set one + None + case Val.Num(_, n) => + Some(n.toInt) + case x => + Error.fail("Cannot xz encode with compression level " + x.prettyName) + } + arg1.force match { + case Val.Str(_, value) => Val.Str(pos, Platform.xzString(value, compressionLevel)) + case arr: Val.Arr => + Val.Str( + pos, + Platform.xzBytes( + arr.iterator.map(_.cast[Val.Num].asInt.toByte).toArray, + compressionLevel + ) + ) + case x => Error.fail("Cannot xz encode " + x.prettyName) + } + } + } + ) +} diff --git a/sjsonnet/src-native/sjsonnet/SjsonnetMain.scala b/sjsonnet/src-native/sjsonnet/SjsonnetMain.scala new file mode 100644 index 000000000..dc544c91d --- /dev/null +++ b/sjsonnet/src-native/sjsonnet/SjsonnetMain.scala @@ -0,0 +1,21 @@ +package sjsonnet + +import sjsonnet.stdlib.{NativeGzip, NativeRegex} + +object SjsonnetMain { + def main(args: Array[String]): Unit = { + val exitCode = SjsonnetMainBase.main0( + args, + new DefaultParseCache, + System.in, + System.out, + System.err, + os.pwd, + None, + std = new Std(nativeFunctions = + Map.from(new NativeGzip().functions ++ new NativeRegex().functions) + ).Std + ) + System.exit(exitCode) + } +} diff --git a/sjsonnet/src/sjsonnet/Std.scala b/sjsonnet/src/sjsonnet/Std.scala index b715fbfe8..d2a8ddcb3 100644 --- a/sjsonnet/src/sjsonnet/Std.scala +++ b/sjsonnet/src/sjsonnet/Std.scala @@ -15,53 +15,17 @@ import scala.collection.mutable * `builtin` and other helpers to handle the common wrapper logic automatically */ class Std( - private val additionalNativeFunctions: Map[String, Val.Func] = Map.empty, + private val nativeFunctions: Map[String, Val.Func] = Map.empty, private val additionalStdFunctions: Map[String, Val.Func] = Map.empty) extends FunctionBuilder { // keep for binary compatibility - def this(additionalNativeFunctions: Map[String, Val.Func]) = - this(additionalNativeFunctions, Map.empty) + def this(nativeFunctions: Map[String, Val.Func]) = + this(nativeFunctions, Map.empty) private val dummyPos: Position = new Position(null, 0) private val emptyLazyArray = new Array[Lazy](0) private val leadingWhiteSpacePattern = Platform.getPatternFromCache("^[ \t\n\f\r\u0085\u00A0']+") private val trailingWhiteSpacePattern = Platform.getPatternFromCache("[ \t\n\f\r\u0085\u00A0']+$") - private val builtinNativeFunctions = Map( - builtin("gzip", "v") { (_, _, v: Val) => - v match { - case Val.Str(_, value) => Platform.gzipString(value) - case arr: Val.Arr => - Platform.gzipBytes(arr.iterator.map(_.cast[Val.Num].asInt.toByte).toArray) - case x => Error.fail("Cannot gzip encode " + x.prettyName) - } - }, - builtinWithDefaults("xz", "v" -> null, "compressionLevel" -> Val.Null(dummyPos)) { - (args, _, _) => - val compressionLevel: Option[Int] = args(1) match { - case Val.Null(_) => - // Use default compression level if the user didn't set one - None - case Val.Num(_, n) => - Some(n.toInt) - case x => - Error.fail("Cannot xz encode with compression level " + x.prettyName) - } - args(0) match { - case Val.Str(_, value) => Platform.xzString(value, compressionLevel) - case arr: Val.Arr => - Platform.xzBytes( - arr.iterator.map(_.cast[Val.Num].asInt.toByte).toArray, - compressionLevel - ) - case x => Error.fail("Cannot xz encode " + x.prettyName) - } - } - ) ++ StdRegex.functions - require( - builtinNativeFunctions.forall(k => !additionalNativeFunctions.contains(k._1)), - "Conflicting native functions" - ) - private val nativeFunctions = builtinNativeFunctions ++ additionalNativeFunctions private object AssertEqual extends Val.Builtin2("assertEqual", "a", "b") { def evalRhs(v1: Lazy, v2: Lazy, ev: EvalScope, pos: Position): Val = { @@ -2000,11 +1964,6 @@ class Std( } }, builtin(Native) - ) ++ builtinNativeFunctions - - require( - functions.forall(k => !additionalStdFunctions.contains(k._1)), - "Conflicting std functions" ) private def toSetArr(args: Array[Val], idx: Int, pos: Position, ev: EvalScope) = { diff --git a/sjsonnet/src/sjsonnet/StdRegex.scala b/sjsonnet/src/sjsonnet/stdlib/NativeRegex.scala similarity index 93% rename from sjsonnet/src/sjsonnet/StdRegex.scala rename to sjsonnet/src/sjsonnet/stdlib/NativeRegex.scala index 4b40af51c..9588f8b9d 100644 --- a/sjsonnet/src/sjsonnet/StdRegex.scala +++ b/sjsonnet/src/sjsonnet/stdlib/NativeRegex.scala @@ -1,9 +1,13 @@ -package sjsonnet +package sjsonnet.stdlib import sjsonnet.Expr.Member.Visibility import sjsonnet.Val.Obj +import sjsonnet._ +import sjsonnet.functions.AbstractFunctionModule + +class NativeRegex extends AbstractFunctionModule { + def name = "regex" -object StdRegex { private final def regexPartialMatch(pos: Position, pattern: String, str: String): Val = { val compiledPattern = Platform.getPatternFromCache(pattern) val matcher = compiledPattern.matcher(str) @@ -39,7 +43,7 @@ object StdRegex { } } - def functions: Map[String, Val.Builtin] = Map( + val functions: Seq[(String, Val.Builtin)] = Seq( "regexPartialMatch" -> new Val.Builtin2("regexPartialMatch", "pattern", "str") { override def evalRhs(pattern: Lazy, str: Lazy, ev: EvalScope, pos: Position): Val = { regexPartialMatch(pos, pattern.force.asString, str.force.asString) diff --git a/sjsonnet/test/resources/test_suite/regex_js.jsonnet b/sjsonnet/test/resources/new_test_suite/regex-js.jsonnet similarity index 100% rename from sjsonnet/test/resources/test_suite/regex_js.jsonnet rename to sjsonnet/test/resources/new_test_suite/regex-js.jsonnet diff --git a/sjsonnet/test/resources/test_suite/regex.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/regex-js.jsonnet.golden similarity index 100% rename from sjsonnet/test/resources/test_suite/regex.jsonnet.golden rename to sjsonnet/test/resources/new_test_suite/regex-js.jsonnet.golden diff --git a/sjsonnet/test/resources/test_suite/regex.jsonnet b/sjsonnet/test/resources/new_test_suite/regex-jvm-native.jsonnet similarity index 100% rename from sjsonnet/test/resources/test_suite/regex.jsonnet rename to sjsonnet/test/resources/new_test_suite/regex-jvm-native.jsonnet diff --git a/sjsonnet/test/resources/test_suite/regex_js.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/regex-jvm-native.jsonnet.golden similarity index 100% rename from sjsonnet/test/resources/test_suite/regex_js.jsonnet.golden rename to sjsonnet/test/resources/new_test_suite/regex-jvm-native.jsonnet.golden diff --git a/sjsonnet/test/src-js/sjsonnet/BaseFileTests.scala b/sjsonnet/test/src-js/sjsonnet/BaseFileTests.scala index a1d178f61..c21cfa834 100644 --- a/sjsonnet/test/src-js/sjsonnet/BaseFileTests.scala +++ b/sjsonnet/test/src-js/sjsonnet/BaseFileTests.scala @@ -1,5 +1,7 @@ package sjsonnet +import sjsonnet.stdlib.NativeRegex + import java.nio.charset.StandardCharsets import scala.scalajs.js import utest._ @@ -7,7 +9,7 @@ import utest._ abstract class BaseFileTests extends TestSuite { private val stderr = new StringBuffer() private val std = new Std( - additionalNativeFunctions = Map( + nativeFunctions = Map( "jsonToString" -> new Val.Builtin1("jsonToString", "x") { override def evalRhs(arg1: Lazy, ev: EvalScope, pos: Position): Val = { Val.Str( @@ -29,7 +31,7 @@ abstract class BaseFileTests extends TestSuite { override def evalRhs(ev: EvalScope, pos: Position): Val = throw new RuntimeException("native function panic") } - ) + ) ++ new NativeRegex().functions ) def importResolver( @@ -103,7 +105,7 @@ abstract class BaseFileTests extends TestSuite { } def check(files: Map[String, () => Array[Byte]], fileName: String, testSuite: String): Unit = { - println(s"Checking $fileName") + println(s"Checking $testSuite/$fileName") val goldenContent = if (files.contains(fileName + ".golden_js")) { new String(files(fileName + ".golden_js")(), StandardCharsets.UTF_8) } else { diff --git a/sjsonnet/test/src-js/sjsonnet/FileTests.scala b/sjsonnet/test/src-js/sjsonnet/FileTests.scala index 737ac46a8..93090e938 100644 --- a/sjsonnet/test/src-js/sjsonnet/FileTests.scala +++ b/sjsonnet/test/src-js/sjsonnet/FileTests.scala @@ -5,7 +5,6 @@ import utest._ object FileTests extends BaseFileTests { val skippedTests = Set( "stdlib.jsonnet", - "regex.jsonnet", // Stack size issues with the JS runner "recursive_function.jsonnet", @@ -55,5 +54,15 @@ object FileTests extends BaseFileTests { check(TestResources_go_test_suite.files, file, "go_test_suite") } } + + test("new_test_suite") - { + val t = TestResources_new_test_suite.files.keys.toSeq + .filter(f => f.matches("[^/]+-js\\.jsonnet")) + .sorted + assert(t.nonEmpty) + t.foreach { file => + check(TestResources_new_test_suite.files, file, "new_test_suite") + } + } } } diff --git a/sjsonnet/test/src-jvm-native/sjsonnet/BaseFileTests.scala b/sjsonnet/test/src-jvm-native/sjsonnet/BaseFileTests.scala index c38078b6e..838553463 100644 --- a/sjsonnet/test/src-jvm-native/sjsonnet/BaseFileTests.scala +++ b/sjsonnet/test/src-jvm-native/sjsonnet/BaseFileTests.scala @@ -1,5 +1,6 @@ package sjsonnet +import sjsonnet.stdlib.NativeRegex import ujson.Value import utest.{TestSuite, assert} @@ -8,7 +9,7 @@ abstract class BaseFileTests extends TestSuite { val testSuiteRoot: os.Path = workspaceRoot / "sjsonnet" / "test" / "resources" private val stderr = new StringBuffer() private val std = new Std( - additionalNativeFunctions = Map( + nativeFunctions = Map( "jsonToString" -> new Val.Builtin1("jsonToString", "x") { override def evalRhs(arg1: Lazy, ev: EvalScope, pos: Position): Val = { Val.Str( @@ -30,7 +31,7 @@ abstract class BaseFileTests extends TestSuite { override def evalRhs(ev: EvalScope, pos: Position): Val = throw new RuntimeException("native function panic") } - ) + ) ++ new NativeRegex().functions ) def eval(p: os.Path, testSuite: String): Either[String, Value] = { @@ -50,7 +51,7 @@ abstract class BaseFileTests extends TestSuite { ), Map("var1" -> "\"test\"", "var2" -> """{"x": 1, "y": 2}"""), OsPath(testSuiteRoot / testSuite), - importer = sjsonnet.SjsonnetMain.resolveImport(Array.empty[Path].toIndexedSeq), + importer = sjsonnet.SjsonnetMainBase.resolveImport(Array.empty[Path].toIndexedSeq), parseCache = new DefaultParseCache, logger = (isTrace: Boolean, msg: String) => { if (isTrace) { diff --git a/sjsonnet/test/src-jvm-native/sjsonnet/FileTests.scala b/sjsonnet/test/src-jvm-native/sjsonnet/FileTests.scala index b92bf1be7..356f8a2e3 100644 --- a/sjsonnet/test/src-jvm-native/sjsonnet/FileTests.scala +++ b/sjsonnet/test/src-jvm-native/sjsonnet/FileTests.scala @@ -4,7 +4,6 @@ import utest.* object FileTests extends BaseFileTests { val testDataSkippedTests: Set[String] = Set( - "regex_js.jsonnet", "stdlib_js.jsonnet" ) ++ (if (isScalaNative) { Set( @@ -48,5 +47,14 @@ object FileTests extends BaseFileTests { check(file, "go_test_suite") } } + test("new_test_suite") - { + val t = os + .list(testSuiteRoot / "new_test_suite") + .filter(f => f.ext == "jsonnet" && f.last.contains("jvm-native")) + assert(t.nonEmpty) + t.foreach { file => + check(file, "new_test_suite") + } + } } } diff --git a/sjsonnet/test/src-jvm-native/sjsonnet/PrettyYamlRendererTests.scala b/sjsonnet/test/src-jvm-native/sjsonnet/PrettyYamlRendererTests.scala index 2dbf43816..03ef28785 100644 --- a/sjsonnet/test/src-jvm-native/sjsonnet/PrettyYamlRendererTests.scala +++ b/sjsonnet/test/src-jvm-native/sjsonnet/PrettyYamlRendererTests.scala @@ -11,7 +11,7 @@ object PrettyYamlRendererTests extends TestSuite { Map(), Map(), OsPath(testSuiteRoot), - importer = sjsonnet.SjsonnetMain.resolveImport(Array(OsPath(testSuiteRoot)).toIndexedSeq), + importer = sjsonnet.SjsonnetMainBase.resolveImport(Array(OsPath(testSuiteRoot)).toIndexedSeq), parseCache = new DefaultParseCache, storePos = if (comments) currentPos = _ else null ) diff --git a/sjsonnet/test/src-jvm-native/sjsonnet/StdGzipTests.scala b/sjsonnet/test/src-jvm-native/sjsonnet/stdlib/NativeGzipTests.scala similarity index 55% rename from sjsonnet/test/src-jvm-native/sjsonnet/StdGzipTests.scala rename to sjsonnet/test/src-jvm-native/sjsonnet/stdlib/NativeGzipTests.scala index 5dd8b4b64..efe17596e 100644 --- a/sjsonnet/test/src-jvm-native/sjsonnet/StdGzipTests.scala +++ b/sjsonnet/test/src-jvm-native/sjsonnet/stdlib/NativeGzipTests.scala @@ -1,12 +1,14 @@ -package sjsonnet +package sjsonnet.stdlib +import sjsonnet.Std import sjsonnet.TestUtils.eval import utest._ -object StdGzipTests extends TestSuite { +object NativeGzipTests extends TestSuite { private val isScalaNative: Boolean = System.getenv("SCALANATIVE_THREAD_STACK_SIZE") != null private val javaVersion: Double = java.lang.Double.parseDouble(System.getProperty("java.specification.version")) + private val std = new Std(nativeFunctions = Map() ++ new NativeGzip().functions) def isJava16OrLater: Boolean = { if (isScalaNative) @@ -17,28 +19,14 @@ object StdGzipTests extends TestSuite { val tests: Tests = Tests { test("gzip") { - eval("""std.gzip([1, 2])""") ==> ujson.Str( + eval("""std.native('gzip')([1, 2])""", std = std) ==> ujson.Str( if (isJava16OrLater) // https://bugs.openjdk.org/browse/JDK-8244706 "H4sIAAAAAAAA/2NkAgCSQsy2AgAAAA==" else "H4sIAAAAAAAAAGNkAgCSQsy2AgAAAA==" ) - eval("""std.gzip("hi")""") ==> ujson.Str( - if (isJava16OrLater) - // https://bugs.openjdk.org/browse/JDK-8244706 - "H4sIAAAAAAAA/8vIBACsKpPYAgAAAA==" - else - "H4sIAAAAAAAAAMvIBACsKpPYAgAAAA==" - ) - eval("""std.native('gzip')([1, 2])""") ==> ujson.Str( - if (isJava16OrLater) - // https://bugs.openjdk.org/browse/JDK-8244706 - "H4sIAAAAAAAA/2NkAgCSQsy2AgAAAA==" - else - "H4sIAAAAAAAAAGNkAgCSQsy2AgAAAA==" - ) - eval("""std.native('gzip')("hi")""") ==> ujson.Str( + eval("""std.native('gzip')("hi")""", std = std) ==> ujson.Str( if (isJava16OrLater) // https://bugs.openjdk.org/browse/JDK-8244706 "H4sIAAAAAAAA/8vIBACsKpPYAgAAAA==" diff --git a/sjsonnet/test/src-jvm/sjsonnet/Example.java b/sjsonnet/test/src-jvm/sjsonnet/Example.java index a171c3c87..2e5aa6ec9 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/Example.java +++ b/sjsonnet/test/src-jvm/sjsonnet/Example.java @@ -4,7 +4,7 @@ public class Example { public void example(){ - sjsonnet.SjsonnetMain.main0( + sjsonnet.SjsonnetMainBase.main0( new String[]{"foo.jsonnet"}, new DefaultParseCache(), System.in, diff --git a/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala b/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala index 86ae504fd..bdfbce7bb 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala @@ -18,7 +18,7 @@ object MainTests extends TestSuite { val outF = File.createTempFile("sjsonnet", ".json") val out = new ByteArrayOutputStream() val pout = new PrintStream(out) - SjsonnetMain.main0( + SjsonnetMainBase.main0( Array(source.toString), new DefaultParseCache, System.in, @@ -28,7 +28,7 @@ object MainTests extends TestSuite { None ) pout.flush() - SjsonnetMain.main0( + SjsonnetMainBase.main0( Array("-o", outF.getAbsolutePath, source.toString), new DefaultParseCache, System.in, @@ -163,7 +163,7 @@ object MainTests extends TestSuite { val perr = new PrintStream(err, true, "UTF-8") val out = new ByteArrayOutputStream() val pout = new PrintStream(out, true, "UTF-8") - val res = SjsonnetMain.main0( + val res = SjsonnetMainBase.main0( args.toArray.flatMap(_.value), new DefaultParseCache, System.in, diff --git a/sjsonnet/test/src-jvm/sjsonnet/StdXzTests.scala b/sjsonnet/test/src-jvm/sjsonnet/StdXzTests.scala deleted file mode 100644 index 2dd25bce7..000000000 --- a/sjsonnet/test/src-jvm/sjsonnet/StdXzTests.scala +++ /dev/null @@ -1,45 +0,0 @@ -package sjsonnet - -import utest._ -import TestUtils.eval - -object StdXzTests extends TestSuite { - val tests: Tests = Tests { - test("xz") { - eval("""std.xz([1, 2])""") ==> ujson.Str( - "/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQABAQIAAADRC9qlUgJ94gABGgLcLqV+H7bzfQEAAAAABFla" - ) - eval("""std.xz("hi")""") ==> ujson.Str( - "/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQABaGkAAAD+qTgRvMqlSAABGgLcLqV+H7bzfQEAAAAABFla" - ) - eval("""std.xz([1, 2], compressionLevel = 0)""") ==> ujson.Str( - "/Td6WFoAAATm1rRGAgAhAQwAAACPmEGcAQABAQIAAADRC9qlUgJ94gABGgLcLqV+H7bzfQEAAAAABFla" - ) - eval("""std.xz("hi", compressionLevel = 1)""") ==> ujson.Str( - "/Td6WFoAAATm1rRGAgAhARAAAACocI6GAQABaGkAAAD+qTgRvMqlSAABGgLcLqV+H7bzfQEAAAAABFla" - ) - var ex = intercept[Exception] { - // Compression level 10 is invalid - eval("""std.xz("hi", 10)""") - } - assert(ex.getMessage.contains("Unsupported preset: 10")) - eval("""std.native('xz')([1, 2])""") ==> ujson.Str( - "/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQABAQIAAADRC9qlUgJ94gABGgLcLqV+H7bzfQEAAAAABFla" - ) - eval("""std.native('xz')("hi")""") ==> ujson.Str( - "/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQABaGkAAAD+qTgRvMqlSAABGgLcLqV+H7bzfQEAAAAABFla" - ) - eval("""std.native('xz')([1, 2], compressionLevel = 0)""") ==> ujson.Str( - "/Td6WFoAAATm1rRGAgAhAQwAAACPmEGcAQABAQIAAADRC9qlUgJ94gABGgLcLqV+H7bzfQEAAAAABFla" - ) - eval("""std.native('xz')("hi", compressionLevel = 1)""") ==> ujson.Str( - "/Td6WFoAAATm1rRGAgAhARAAAACocI6GAQABaGkAAAD+qTgRvMqlSAABGgLcLqV+H7bzfQEAAAAABFla" - ) - ex = intercept[Exception] { - // Compression level 10 is invalid - eval("""std.native('xz')("hi", 10)""") - } - assert(ex.getMessage.contains("Unsupported preset: 10")) - } - } -} diff --git a/sjsonnet/test/src-jvm/sjsonnet/stdlib/NativeXzTests.scala b/sjsonnet/test/src-jvm/sjsonnet/stdlib/NativeXzTests.scala new file mode 100644 index 000000000..e3b05efaf --- /dev/null +++ b/sjsonnet/test/src-jvm/sjsonnet/stdlib/NativeXzTests.scala @@ -0,0 +1,31 @@ +package sjsonnet.stdlib + +import sjsonnet.Std +import sjsonnet.TestUtils.eval +import utest.* + +object NativeXzTests extends TestSuite { + private val std = new Std(nativeFunctions = Map() ++ new NativeXz().functions) + + val tests: Tests = Tests { + test("xz") { + eval("""std.native('xz')([1, 2])""", std = std) ==> ujson.Str( + "/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQABAQIAAADRC9qlUgJ94gABGgLcLqV+H7bzfQEAAAAABFla" + ) + eval("""std.native('xz')("hi")""", std = std) ==> ujson.Str( + "/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQABaGkAAAD+qTgRvMqlSAABGgLcLqV+H7bzfQEAAAAABFla" + ) + eval("""std.native('xz')([1, 2], compressionLevel = 0)""", std = std) ==> ujson.Str( + "/Td6WFoAAATm1rRGAgAhAQwAAACPmEGcAQABAQIAAADRC9qlUgJ94gABGgLcLqV+H7bzfQEAAAAABFla" + ) + eval("""std.native('xz')("hi", compressionLevel = 1)""", std = std) ==> ujson.Str( + "/Td6WFoAAATm1rRGAgAhARAAAACocI6GAQABaGkAAAD+qTgRvMqlSAABGgLcLqV+H7bzfQEAAAAABFla" + ) + val ex = intercept[Exception] { + // Compression level 10 is invalid + eval("""std.native('xz')("hi", 10)""", std = std) + } + assert(ex.getMessage.contains("Unsupported preset: 10")) + } + } +} diff --git a/sjsonnet/test/src/sjsonnet/TestUtils.scala b/sjsonnet/test/src/sjsonnet/TestUtils.scala index e817ad0eb..53a6905cd 100644 --- a/sjsonnet/test/src/sjsonnet/TestUtils.scala +++ b/sjsonnet/test/src/sjsonnet/TestUtils.scala @@ -7,7 +7,8 @@ object TestUtils { s: String, preserveOrder: Boolean = false, strict: Boolean = false, - useNewEvaluator: Boolean = false): Either[String, Value] = { + useNewEvaluator: Boolean = false, + std: Std = new Std()): Either[String, Value] = { new Interpreter( Map(), Map(), @@ -19,7 +20,8 @@ object TestUtils { strict = strict, throwErrorForInvalidSets = true, useNewEvaluator = useNewEvaluator - ) + ), + std = std.Std ).interpret(s, DummyPath("(memory)")) } @@ -27,12 +29,14 @@ object TestUtils { s: String, preserveOrder: Boolean = false, strict: Boolean = false, - useNewEvaluator: Boolean = false): Value = { + useNewEvaluator: Boolean = false, + std: Std = new Std()): Value = { eval0( s, preserveOrder, strict, - useNewEvaluator + useNewEvaluator, + std ) match { case Right(x) => x case Left(e) => throw new Exception(e) @@ -43,12 +47,14 @@ object TestUtils { s: String, preserveOrder: Boolean = false, strict: Boolean = false, - useNewEvaluator: Boolean = false): String = { + useNewEvaluator: Boolean = false, + std: Std = new Std()): String = { eval0( s, preserveOrder, strict, - useNewEvaluator + useNewEvaluator, + std ) match { case Left(err) => err.split('\n').map(_.trim).mkString("\n") // normalize inconsistent indenation on JVM vs JS