diff --git a/.gitignore b/.gitignore index a6fcde6..a463476 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/ +testData/** ### IntelliJ IDEA ### .idea/modules.xml @@ -45,6 +46,7 @@ build/ ### Scala ### .bsp/ +*.semanticdb ### IDEA ### /.idea/ diff --git a/build.sbt b/build.sbt index 09be481..23e207d 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ resolvers += "Sonatype OSS Snapshots" at "https://s01.oss.sonatype.org/content/repositories/snapshots" lazy val jenaV = "5.3.0" -lazy val jellyV = "2.8.0+14-4181e89a-SNAPSHOT" +lazy val jellyV = "2.8.0" addCommandAlias("fixAll", "scalafixAll; scalafmtAll") diff --git a/src/main/resources/META-INF/native-image/com.github.ben-manes.caffeine/caffeine/reflect-config.json b/src/main/resources/META-INF/native-image/com.github.ben-manes.caffeine/caffeine/reflect-config.json new file mode 100644 index 0000000..feb2266 --- /dev/null +++ b/src/main/resources/META-INF/native-image/com.github.ben-manes.caffeine/caffeine/reflect-config.json @@ -0,0 +1,605 @@ +[ + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BBHeader$ReadAndWriteCounterRef" + }, + "name": "com.github.benmanes.caffeine.cache.BBHeader$ReadAndWriteCounterRef", + "fields": [ + { + "name": "writeCounter" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BBHeader$ReadAndWriteCounterRef" + }, + "name": "com.github.benmanes.caffeine.cache.BBHeader$ReadCounterRef", + "fields": [ + { + "name": "readCounter" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BLCHeader$DrainStatusRef" + }, + "name": "com.github.benmanes.caffeine.cache.BLCHeader$DrainStatusRef", + "fields": [ + { + "name": "drainStatus" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueue" + }, + "name": "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueColdProducerFields", + "fields": [ + { + "name": "producerLimit" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueue" + }, + "name": "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueConsumerFields", + "fields": [ + { + "name": "consumerIndex" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueue" + }, + "name": "com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueProducerFields", + "fields": [ + { + "name": "producerIndex" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache" + }, + "name": "com.github.benmanes.caffeine.cache.BoundedLocalCache", + "fields": [ + { + "name": "refreshes" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.Caffeine" + }, + "name": "com.github.benmanes.caffeine.cache.CacheLoader", + "methods": [ + { + "name": "asyncLoadAll", + "parameterTypes": [ + "java.util.Set", + "java.util.concurrent.Executor" + ] + }, + { + "name": "loadAll", + "parameterTypes": [ + "java.util.Set" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.LocalLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.CacheLoader", + "methods": [ + { + "name": "loadAll", + "parameterTypes": [ + "java.util.Set" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.FS" + }, + "name": "com.github.benmanes.caffeine.cache.FS", + "fields": [ + { + "name": "key" + }, + { + "name": "value" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.WS" + }, + "name": "com.github.benmanes.caffeine.cache.FS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.FW" + }, + "name": "com.github.benmanes.caffeine.cache.FW", + "fields": [ + { + "name": "value" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.WI" + }, + "name": "com.github.benmanes.caffeine.cache.FW", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.PD" + }, + "name": "com.github.benmanes.caffeine.cache.PD", + "fields": [ + { + "name": "value" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.PS" + }, + "name": "com.github.benmanes.caffeine.cache.PS", + "fields": [ + { + "name": "key" + }, + { + "name": "value" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.PSA" + }, + "name": "com.github.benmanes.caffeine.cache.PSA", + "fields": [ + { + "name": "accessTime" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.SSA" + }, + "name": "com.github.benmanes.caffeine.cache.PSA", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.SSSMS" + }, + "name": "com.github.benmanes.caffeine.cache.PSMS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.SSMW" + }, + "name": "com.github.benmanes.caffeine.cache.PSMW", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.PSR" + }, + "name": "com.github.benmanes.caffeine.cache.PSR", + "fields": [ + { + "name": "writeTime" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.SSMSR" + }, + "name": "com.github.benmanes.caffeine.cache.PSRMS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.PSW" + }, + "name": "com.github.benmanes.caffeine.cache.PSW", + "fields": [ + { + "name": "writeTime" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.SSA" + }, + "name": "com.github.benmanes.caffeine.cache.PSW", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.SSW" + }, + "name": "com.github.benmanes.caffeine.cache.PSW", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.SSSMW" + }, + "name": "com.github.benmanes.caffeine.cache.PSWMW", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.PW" + }, + "name": "com.github.benmanes.caffeine.cache.PW", + "fields": [ + { + "name": "value" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalManualCache" + }, + "name": "com.github.benmanes.caffeine.cache.SI", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSA", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "name": "com.github.benmanes.caffeine.cache.SSMS", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSMSR", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalAsyncCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSMSW", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalAsyncLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSMSW", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalManualCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSMSW", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSMW", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalManualCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSSMS", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSSMWW", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.SSW", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.StripedBuffer" + }, + "name": "com.github.benmanes.caffeine.cache.StripedBuffer", + "fields": [ + { + "name": "tableBusy" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.UnboundedLocalCache" + }, + "name": "com.github.benmanes.caffeine.cache.UnboundedLocalCache", + "fields": [ + { + "name": "refreshes" + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.WI", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalLoadingCache" + }, + "name": "com.github.benmanes.caffeine.cache.WS", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.Caffeine" + }, + "name": "com.github.benmanes.caffeine.cache.WS", + "methods": [ + { + "name": "", + "parameterTypes": [ + "com.github.benmanes.caffeine.cache.Caffeine", + "com.github.benmanes.caffeine.cache.AsyncCacheLoader", + "boolean" + ] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.NodeFactory" + }, + "name": "com.github.benmanes.caffeine.cache.PSWMS", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.NodeFactory" + }, + "name": "com.github.benmanes.caffeine.cache.PD", + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "condition": { + "typeReachable": "com.github.benmanes.caffeine.cache.NodeFactory" + }, + "name": "com.github.benmanes.caffeine.cache.PW", + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/src/main/scala/eu/neverblink/jelly/cli/App.scala b/src/main/scala/eu/neverblink/jelly/cli/App.scala index 6741882..bb1c8de 100644 --- a/src/main/scala/eu/neverblink/jelly/cli/App.scala +++ b/src/main/scala/eu/neverblink/jelly/cli/App.scala @@ -3,10 +3,14 @@ package eu.neverblink.jelly.cli import caseapp.* import eu.neverblink.jelly.cli.command.* import eu.neverblink.jelly.cli.command.rdf.* +import org.apache.jena.sys.JenaSystem /** Main entrypoint. */ object App extends CommandsEntryPoint: + // Initialize Jena now to avoid race conditions later + JenaSystem.init() + override def progName: String = "jelly-cli" override def commands: Seq[Command[?]] = Seq( diff --git a/src/main/scala/eu/neverblink/jelly/cli/JellyCommand.scala b/src/main/scala/eu/neverblink/jelly/cli/JellyCommand.scala index 9bb527e..69d3e32 100644 --- a/src/main/scala/eu/neverblink/jelly/cli/JellyCommand.scala +++ b/src/main/scala/eu/neverblink/jelly/cli/JellyCommand.scala @@ -3,7 +3,7 @@ package eu.neverblink.jelly.cli import caseapp.* import eu.neverblink.jelly.cli.JellyCommand.emptyRemainingArgs -import java.io.{ByteArrayOutputStream, PrintStream} +import java.io.{ByteArrayOutputStream, OutputStream, PrintStream} import scala.compiletime.uninitialized object JellyCommand: @@ -39,6 +39,10 @@ abstract class JellyCommand[T: {Parser, Help}] extends Command[T]: s else throw new IllegalStateException("Not in test mode") + protected def getStdOut: OutputStream = + if isTest then osOut + else System.out + def getErr: String = if isTest then err.flush() diff --git a/src/main/scala/eu/neverblink/jelly/cli/command/rdf/RdfFromJelly.scala b/src/main/scala/eu/neverblink/jelly/cli/command/rdf/RdfFromJelly.scala index 31af120..f6185ff 100644 --- a/src/main/scala/eu/neverblink/jelly/cli/command/rdf/RdfFromJelly.scala +++ b/src/main/scala/eu/neverblink/jelly/cli/command/rdf/RdfFromJelly.scala @@ -1,16 +1,43 @@ package eu.neverblink.jelly.cli.command.rdf import caseapp.* import eu.neverblink.jelly.cli.JellyCommand +import eu.ostrzyciel.jelly.convert.jena.riot.{JellyLanguage, JellySubsystemLifecycle} +import org.apache.jena.riot.system.StreamRDFWriter +import org.apache.jena.riot.{RDFLanguages, RDFParser} -case class FromJellyRdfOptions() +import java.io.{File, FileInputStream, FileOutputStream, InputStream, OutputStream} + +case class RdfFromJellyOptions( + @ExtraName("to") outputFile: Option[String] = None, +) + +object RdfFromJelly extends JellyCommand[RdfFromJellyOptions]: + override def group = "rdf" -object RdfFromJelly extends JellyCommand[FromJellyRdfOptions]: override def names: List[List[String]] = List( List("rdf", "from-jelly"), ) - override def run(options: FromJellyRdfOptions, remainingArgs: RemainingArgs): Unit = - // This is a placeholder for the actual implementation - println("rdf from-jelly") - println(options) - println(remainingArgs) + override def run(options: RdfFromJellyOptions, remainingArgs: RemainingArgs): Unit = + val inputStream = remainingArgs.remaining.headOption match { + case Some(fileName: String) => + FileInputStream(File(fileName)) + case _ => System.in + } + val outputStream = options.outputFile match { + case Some(fileName: String) => + FileOutputStream(fileName) + case None => getStdOut + } + doConversion(inputStream, outputStream) + + /* + This method reads the Jelly file, rewrite it to NQuads and writes it to some output stream + * @param inputStream InputStream + * @param outputStream OutputStream + */ + private def doConversion(inputStream: InputStream, outputStream: OutputStream): Unit = + val mod = JellySubsystemLifecycle() + mod.start() + val nQuadWriter = StreamRDFWriter.getWriterStream(outputStream, RDFLanguages.NQUADS) + RDFParser.source(inputStream).lang(JellyLanguage.JELLY).parse(nQuadWriter) diff --git a/src/test/scala/eu/neverblink/jelly/cli/command/RdfFromJellySpec.scala b/src/test/scala/eu/neverblink/jelly/cli/command/RdfFromJellySpec.scala index 1b5f9ed..e7721bd 100644 --- a/src/test/scala/eu/neverblink/jelly/cli/command/RdfFromJellySpec.scala +++ b/src/test/scala/eu/neverblink/jelly/cli/command/RdfFromJellySpec.scala @@ -1,12 +1,65 @@ package eu.neverblink.jelly.cli.command +import caseapp.core.{Indexed, RemainingArgs} import eu.neverblink.jelly.cli.command.helpers.* +import eu.neverblink.jelly.cli.command.rdf.* +import org.apache.jena.riot.RDFLanguages import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -class RdfFromJellySpec extends AnyWordSpec with Matchers with CleanUpFilesAfterTest: +import scala.io.Source +import scala.util.Using + +class RdfFromJellySpec extends AnyWordSpec with Matchers with CleanUpAfterTest: "rdf from-jelly command" should { - "be able to convert a Jelly file to NTriples" in { + "be able to convert a Jelly file to NTriples output stream" in { val jellyFile = DataGenHelper.generateJellyFile(3) + val nQuadString = DataGenHelper.generateNQuadString(3) + val options = RdfFromJellyOptions(outputFile = None) + val args = RemainingArgs(indexedRemaining = List(Indexed(jellyFile)), Seq.empty) + val (out, err) = + RdfFromJelly.runTest( + options, + args, + ) + val sortedOut = out.split("\n").map(_.trim).sorted + val sortedQuads = nQuadString.split("\n").map(_.trim).sorted + sortedOut should contain theSameElementsAs sortedQuads + } + "be able to convert a Jelly stream to NTriples output stream" in { + DataGenHelper.generateJellyInputStream(3) + val nQuadString = DataGenHelper.generateNQuadString(3) + val options = RdfFromJellyOptions(outputFile = None) + val (out, err) = RdfFromJelly.runTest(options) + val sortedOut = out.split("\n").map(_.trim).sorted + val sortedQuads = nQuadString.split("\n").map(_.trim).sorted + sortedOut should contain theSameElementsAs sortedQuads + } + "be able to convert a Jelly file to NTriples file" in { + val jellyFile = DataGenHelper.generateJellyFile(3) + val args = RemainingArgs(indexedRemaining = List(Indexed(jellyFile)), Seq.empty) + val nQuadString = DataGenHelper.generateNQuadString(3) + val outputFile = DataGenHelper.generateOutputFile(RDFLanguages.NQUADS) + val options = RdfFromJellyOptions(outputFile = Some(outputFile)) + val (out, err) = RdfFromJelly.runTest(options, args) + val sortedOut = Using.resource(Source.fromFile(outputFile)) { content => + content.getLines().toList.map(_.trim).sorted + } + val sortedQuads = nQuadString.split("\n").map(_.trim).sorted + sortedOut should contain theSameElementsAs sortedQuads + out.length should be(0) + } + "be able to convert a Jelly stream to NTriples file" in { + DataGenHelper.generateJellyInputStream(3) + val outputFile = DataGenHelper.generateOutputFile(RDFLanguages.NQUADS) + val nQuadString = DataGenHelper.generateNQuadString(3) + val options = RdfFromJellyOptions(outputFile = Some(outputFile)) + val (out, err) = RdfFromJelly.runTest(options) + val sortedOut = Using.resource(Source.fromFile(outputFile)) { content => + content.getLines().toList.map(_.trim).sorted + } + val sortedQuads = nQuadString.split("\n").map(_.trim).sorted + sortedOut should contain theSameElementsAs sortedQuads + out.length should be(0) } } diff --git a/src/test/scala/eu/neverblink/jelly/cli/command/helpers/CleanUpFilesAfterTest.scala b/src/test/scala/eu/neverblink/jelly/cli/command/helpers/CleanUpAfterTest.scala similarity index 61% rename from src/test/scala/eu/neverblink/jelly/cli/command/helpers/CleanUpFilesAfterTest.scala rename to src/test/scala/eu/neverblink/jelly/cli/command/helpers/CleanUpAfterTest.scala index 6a3c705..4d73c62 100644 --- a/src/test/scala/eu/neverblink/jelly/cli/command/helpers/CleanUpFilesAfterTest.scala +++ b/src/test/scala/eu/neverblink/jelly/cli/command/helpers/CleanUpAfterTest.scala @@ -3,9 +3,10 @@ package eu.neverblink.jelly.cli.command.helpers import org.scalatest.BeforeAndAfterEach import org.scalatest.wordspec.AnyWordSpec -trait CleanUpFilesAfterTest extends BeforeAndAfterEach { +trait CleanUpAfterTest extends BeforeAndAfterEach { this: AnyWordSpec => override def afterEach(): Unit = { - DataGenHelper.cleanUpFile() + DataGenHelper.cleanUpFiles() + DataGenHelper.resetInputStream() } } diff --git a/src/test/scala/eu/neverblink/jelly/cli/command/helpers/DataGenHelper.scala b/src/test/scala/eu/neverblink/jelly/cli/command/helpers/DataGenHelper.scala index d81cf91..d6e5f89 100644 --- a/src/test/scala/eu/neverblink/jelly/cli/command/helpers/DataGenHelper.scala +++ b/src/test/scala/eu/neverblink/jelly/cli/command/helpers/DataGenHelper.scala @@ -2,10 +2,11 @@ package eu.neverblink.jelly.cli.command.helpers import eu.ostrzyciel.jelly.convert.jena.riot.JellyLanguage import org.apache.jena.rdf.model.{Model, ModelFactory, ResourceFactory} -import org.apache.jena.riot.RDFDataMgr +import org.apache.jena.riot.{RDFDataMgr, RDFLanguages, Lang} -import java.io.FileOutputStream +import java.io.{ByteArrayInputStream, ByteArrayOutputStream, FileOutputStream} import java.nio.file.{Files, Paths} +import scala.collection.mutable.ListBuffer import scala.util.Using /* @@ -14,6 +15,8 @@ import scala.util.Using object DataGenHelper: private val testFile = "testInput.jelly" + private val inputStream = System.in + protected val outputFiles = ListBuffer[String]() /* * This method generates a triple model with nTriples @@ -37,14 +40,50 @@ object DataGenHelper: /* This method generates a Jelly file with nTriples * @param nTriples number of triples to generate * @param fileName name of the file to generate + * @return String */ - def generateJellyFile(nTriples: Int): Unit = + def generateJellyFile(nTriples: Int): String = val model = generateTripleModel(nTriples) // TODO: Add configurable generation for different variants of Jelly (small strict etc) Using.resource(FileOutputStream(testFile)) { file => RDFDataMgr.write(file, model, JellyLanguage.JELLY) } + testFile - /* This method cleans up the file after the test*/ - def cleanUpFile(): Unit = + /* + * This method generates a Jelly byte input stream with nTriples + * @param nTriples number of triples to generate + */ + def generateJellyInputStream(nTriples: Int): Unit = + val model = generateTripleModel(nTriples) + val outputStream = new ByteArrayOutputStream() + RDFDataMgr.write(outputStream, model, JellyLanguage.JELLY) + val jellyStream = new ByteArrayInputStream(outputStream.toByteArray) + System.setIn(jellyStream) + + /* + * This method generates a NQuad string with nTriples + * @param nTriples number of triples to generate + * @return String + */ + def generateNQuadString(nTriples: Int): String = + val model = generateTripleModel(nTriples) + val outputStream = new ByteArrayOutputStream() + RDFDataMgr.write(outputStream, model, RDFLanguages.NQUADS) + outputStream.toString + + /* + * Generates and then cleans the file for test purposes + */ + def generateOutputFile(format: Lang = RDFLanguages.NQUADS): String = + val extension = format.getFileExtensions.get(0) + val fileName = s"testOutput${outputFiles.size}.${extension}" + outputFiles += fileName + fileName + + def cleanUpFiles(): Unit = Files.deleteIfExists(Paths.get(testFile)) + for file <- outputFiles do Files.deleteIfExists(Paths.get(file)) + + def resetInputStream(): Unit = + System.setIn(inputStream)