From 1a9b40e94c5865b2b70d133cbc15f4800402fda8 Mon Sep 17 00:00:00 2001 From: niegrzybkowski Date: Fri, 11 Jul 2025 13:25:59 +0200 Subject: [PATCH 1/6] Add all charsets for GraalVM --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index 387ca96..4729daf 100644 --- a/build.sbt +++ b/build.sbt @@ -26,6 +26,7 @@ lazy val graalOptions = Seq( ).flatten ++ Seq( "--features=eu.neverblink.jelly.cli.graal.ProtobufFeature", "-H:ReflectionConfigurationFiles=" + file("graal.json").getAbsolutePath, + "-H:+AddAllCharsets", // TODO: only add necessary charsets ) lazy val root = (project in file(".")) From 3fa401f4e95a6c4fcffa4f859e2705ee306d1937 Mon Sep 17 00:00:00 2001 From: niegrzybkowski Date: Fri, 11 Jul 2025 15:23:15 +0200 Subject: [PATCH 2/6] Fix containsAll tests --- .../cli/command/rdf/RdfToJellySpec.scala | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala b/src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala index 86f636a..526aafc 100644 --- a/src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala +++ b/src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala @@ -50,7 +50,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: // Make sure it's written in the delimited format IoUtils.autodetectDelimiting(new ByteArrayInputStream(bytes)).isDelimited should be(true) val content = translateJellyBack(ByteArrayInputStream(bytes)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true } "a file to file" in withFullJenaFile { f => @@ -58,7 +58,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: val (out, err) = RdfToJelly.runTestCommand(List("rdf", "to-jelly", "--to", j, f)) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true } } @@ -71,7 +71,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(tripleModel.listStatements()) + content.containsAll(tripleModel.listStatements()) shouldBe true } "input stream to output stream, generalized RDF (N-Triples)" in { @@ -160,7 +160,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: val tripleModel = DataGenHelper.generateTripleModel(testCardinality) val (out, err) = RdfToJelly.runTestCommand(List("rdf", "to-jelly", "--to", j)) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(tripleModel.listStatements()) + content.containsAll(tripleModel.listStatements()) shouldBe true } "a file to file, modified stream options" in withFullJenaFile { f => @@ -183,7 +183,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true val frames = readJellyFile(new FileInputStream(j)) val opts = frames.head.getRows.asScala.head.getOptions opts.getStreamName should be("testName") @@ -211,7 +211,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true val frames = readJellyFile(new FileInputStream(j)) val opts = frames.head.getRows.asScala.head.getOptions opts.getStreamName should be("") @@ -241,7 +241,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true val frames = readJellyFile(new FileInputStream(j)) val opts = frames.head.getRows.asScala.head.getOptions opts.getStreamName should be("") @@ -270,7 +270,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true val frames = readJellyFile(new FileInputStream(j)) frames.size should be > 3 for frame <- frames do @@ -294,7 +294,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true // Note: no actual namespace declarations are present in the test data, because it's // N-Quads. // TODO: test if the namespace declarations are preserved with Turtle or RDF/XML input. @@ -336,7 +336,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true } "a file to file, physical type set to TRIPLES, logical type to GRAPHS" in withFullJenaFile( testCode = { f => @@ -356,7 +356,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: val content = translateJellyBack(new FileInputStream(j)) content.containsAll( DataGenHelper.generateTripleModel(testCardinality).listStatements(), - ) + ) shouldBe true val frames = readJellyFile(new FileInputStream(j)) val opts = frames.head.getRows.asScala.head.getOptions opts.getStreamName should be("") @@ -392,7 +392,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: val content = translateJellyBack(new FileInputStream(j)) content.containsAll( DataGenHelper.generateTripleModel(testCardinality).listStatements(), - ) + ) shouldBe true val frames = readJellyFile(new FileInputStream(j)) val opts = frames.head.getRows.asScala.head.getOptions opts.getStreamName should be("") @@ -422,7 +422,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true } "TriG" in withFullJenaFile( testCode = { f => @@ -430,7 +430,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: RdfToJelly.runTestCommand(List("rdf", "to-jelly", f)) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true }, jenaLang = RDFLanguages.TRIG, ) @@ -442,7 +442,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true }, jenaLang = RDFLanguages.RDFPROTO, ) @@ -452,7 +452,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: RdfToJelly.runTestCommand(List("rdf", "to-jelly", f)) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true }, jenaLang = RDFLanguages.RDFTHRIFT, ) @@ -464,7 +464,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true }, jenaLang = RDFLanguages.RDFXML, ) @@ -476,7 +476,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true }, jenaLang = RDFLanguages.JSONLD, ) @@ -494,7 +494,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(outFile)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true RdfToJelly.getErrString should include("WARNING: The Jelly text format is not stable") } } @@ -530,7 +530,7 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(outFile)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) + content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true } } From 9fdf50511c063b3f15275583cf3369b0cbbcf26e Mon Sep 17 00:00:00 2001 From: niegrzybkowski Date: Fri, 11 Jul 2025 15:26:00 +0200 Subject: [PATCH 3/6] Add a missing finish() call to jellyWriter --- .../scala/eu/neverblink/jelly/cli/command/rdf/RdfToJelly.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJelly.scala b/src/main/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJelly.scala index 2575771..65f65ac 100644 --- a/src/main/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJelly.scala +++ b/src/main/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJelly.scala @@ -160,6 +160,7 @@ object RdfToJelly extends RdfSerDesCommand[RdfToJellyOptions, RdfFormat.Readable JellyStreamWriter(JenaConverterFactory.getInstance(), variant, outputStream) RDFParser.source(inputStream).lang(jenaLang).parse(jellyWriter) + jellyWriter.finish() /** Convert Jelly text to Jelly binary. * @param inputStream From 873afac32aec8067d40d25cd55670c72fe2d4b80 Mon Sep 17 00:00:00 2001 From: niegrzybkowski Date: Fri, 11 Jul 2025 15:26:30 +0200 Subject: [PATCH 4/6] Add small AOT test for jsonld input --- .github/workflows/aot-test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/aot-test.yml b/.github/workflows/aot-test.yml index c7b7c81..c2240d7 100644 --- a/.github/workflows/aot-test.yml +++ b/.github/workflows/aot-test.yml @@ -42,6 +42,9 @@ jobs: target/graalvm-native-image/jelly-cli \ rdf from-jelly --out-format=jsonld out.jelly > out.json && \ [ -s out.json ] + echo '{"@graph":[{"@id":"http://e.org/r","http://e.org/p":{"@value":"v"}}]}' | \ + target/graalvm-native-image/jelly-cli rdf to-jelly --in-format "jsonld" > jsonld.jelly && \ + [ -s jsonld.jelly ] - name: Upload binary uses: actions/upload-artifact@v4 From d784eb28d5452ee260ff41f8c8e5c67608d3d781 Mon Sep 17 00:00:00 2001 From: niegrzybkowski Date: Fri, 11 Jul 2025 15:28:54 +0200 Subject: [PATCH 5/6] Didn't notice the changes whoops --- .../cli/command/rdf/RdfToJellySpec.scala | 64 ++++++++++++++----- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala b/src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala index 526aafc..129b2c0 100644 --- a/src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala +++ b/src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala @@ -50,7 +50,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: // Make sure it's written in the delimited format IoUtils.autodetectDelimiting(new ByteArrayInputStream(bytes)).isDelimited should be(true) val content = translateJellyBack(ByteArrayInputStream(bytes)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true } "a file to file" in withFullJenaFile { f => @@ -58,7 +60,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: val (out, err) = RdfToJelly.runTestCommand(List("rdf", "to-jelly", "--to", j, f)) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true } } @@ -183,7 +187,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true val frames = readJellyFile(new FileInputStream(j)) val opts = frames.head.getRows.asScala.head.getOptions opts.getStreamName should be("testName") @@ -211,7 +217,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true val frames = readJellyFile(new FileInputStream(j)) val opts = frames.head.getRows.asScala.head.getOptions opts.getStreamName should be("") @@ -241,7 +249,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true val frames = readJellyFile(new FileInputStream(j)) val opts = frames.head.getRows.asScala.head.getOptions opts.getStreamName should be("") @@ -270,7 +280,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true val frames = readJellyFile(new FileInputStream(j)) frames.size should be > 3 for frame <- frames do @@ -294,7 +306,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(j)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true // Note: no actual namespace declarations are present in the test data, because it's // N-Quads. // TODO: test if the namespace declarations are preserved with Turtle or RDF/XML input. @@ -336,7 +350,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true } "a file to file, physical type set to TRIPLES, logical type to GRAPHS" in withFullJenaFile( testCode = { f => @@ -422,7 +438,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true } "TriG" in withFullJenaFile( testCode = { f => @@ -430,7 +448,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: RdfToJelly.runTestCommand(List("rdf", "to-jelly", f)) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true }, jenaLang = RDFLanguages.TRIG, ) @@ -442,7 +462,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true }, jenaLang = RDFLanguages.RDFPROTO, ) @@ -452,7 +474,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: RdfToJelly.runTestCommand(List("rdf", "to-jelly", f)) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true }, jenaLang = RDFLanguages.RDFTHRIFT, ) @@ -464,7 +488,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true }, jenaLang = RDFLanguages.RDFXML, ) @@ -476,7 +502,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ) val newIn = new ByteArrayInputStream(RdfToJelly.getOutBytes) val content = translateJellyBack(newIn) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true }, jenaLang = RDFLanguages.JSONLD, ) @@ -494,7 +522,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(outFile)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true RdfToJelly.getErrString should include("WARNING: The Jelly text format is not stable") } } @@ -530,7 +560,9 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers: ), ) val content = translateJellyBack(new FileInputStream(outFile)) - content.containsAll(DataGenHelper.generateTripleModel(testCardinality).listStatements()) shouldBe true + content.containsAll( + DataGenHelper.generateTripleModel(testCardinality).listStatements(), + ) shouldBe true } } From 777b339c3fae529f25280187873e8566d9afecb2 Mon Sep 17 00:00:00 2001 From: niegrzybkowski Date: Fri, 11 Jul 2025 15:59:12 +0200 Subject: [PATCH 6/6] Add a link to the unnecessary charsets issue --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4729daf..608ac93 100644 --- a/build.sbt +++ b/build.sbt @@ -26,7 +26,7 @@ lazy val graalOptions = Seq( ).flatten ++ Seq( "--features=eu.neverblink.jelly.cli.graal.ProtobufFeature", "-H:ReflectionConfigurationFiles=" + file("graal.json").getAbsolutePath, - "-H:+AddAllCharsets", // TODO: only add necessary charsets + "-H:+AddAllCharsets", // TODO: only add necessary charsets github.com/Jelly-RDF/cli/issues/154 ) lazy val root = (project in file("."))