From d5edf5e9899f9f7c8ba9dad0058174f18114ad38 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 26 Nov 2023 11:37:07 +0300 Subject: [PATCH] fix pandoc tests --- build.gradle.kts | 2 +- gradle.properties | 2 +- .../space/kscience/snark/SnarkParser.kt | 10 +- .../kscience/snark/html/ImageIOReader.kt | 5 +- .../space/kscience/snark/html/SiteLayout.kt | 4 +- .../kscience/snark/html/SnarkHtmlPlugin.kt | 3 +- .../kscience/snark/html/StaticSiteBuilder.kt | 7 +- .../kscience/snark/html/TextProcessor.kt | 5 +- .../space/kscience/snark/pandoc/Pandoc.kt | 43 +++---- .../kscience/snark/pandoc/PandocInstaller.kt | 2 +- snark-pandoc/src/jvmTest/kotlin/PandocTest.kt | 114 +++++++++--------- .../jvmTest/resources}/first_test.md | 0 .../jvmTest/resources}/simple.txt | 0 13 files changed, 89 insertions(+), 108 deletions(-) rename snark-pandoc/{testing_directory => src/jvmTest/resources}/first_test.md (100%) rename snark-pandoc/{testing_directory => src/jvmTest/resources}/simple.txt (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 0ac1937..38da2b8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ allprojects { } } -val dataforgeVersion by extra("0.6.2") +val dataforgeVersion by extra("0.7.0") ksciencePublish { pom("https://github.com/SciProgCentre/snark") { diff --git a/gradle.properties b/gradle.properties index c53e77f..2495fa6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official -toolsVersion=0.15.0-kotlin-1.9.20 \ No newline at end of file +toolsVersion=0.15.1-kotlin-1.9.21 \ No newline at end of file diff --git a/snark-core/src/commonMain/kotlin/space/kscience/snark/SnarkParser.kt b/snark-core/src/commonMain/kotlin/space/kscience/snark/SnarkParser.kt index d17967f..f8a718e 100644 --- a/snark-core/src/commonMain/kotlin/space/kscience/snark/SnarkParser.kt +++ b/snark-core/src/commonMain/kotlin/space/kscience/snark/SnarkParser.kt @@ -1,20 +1,20 @@ package space.kscience.snark -import io.ktor.utils.io.core.Input -import io.ktor.utils.io.core.readBytes +import kotlinx.io.Source +import kotlinx.io.readByteArray import space.kscience.dataforge.context.Context import space.kscience.dataforge.io.IOReader import space.kscience.dataforge.io.asBinary import space.kscience.dataforge.io.readWith import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.misc.Type +import space.kscience.dataforge.misc.DfId import kotlin.reflect.KType import kotlin.reflect.typeOf /** * A parser of binary content including priority flag and file extensions */ -@Type(SnarkParser.TYPE) +@DfId(SnarkParser.TYPE) public interface SnarkParser { public val type: KType @@ -28,7 +28,7 @@ public interface SnarkParser { public fun asReader(context: Context, meta: Meta): IOReader = object : IOReader { override val type: KType get() = this@SnarkParser.type - override fun readObject(input: Input): R = parse(context, meta, input.readBytes()) + override fun readFrom(source: Source): R = parse(context, meta, source.readByteArray()) } public companion object { diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/ImageIOReader.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/ImageIOReader.kt index 84d52e5..506881f 100644 --- a/snark-html/src/main/kotlin/space/kscience/snark/html/ImageIOReader.kt +++ b/snark-html/src/main/kotlin/space/kscience/snark/html/ImageIOReader.kt @@ -1,7 +1,8 @@ package space.kscience.snark.html import io.ktor.util.asStream -import io.ktor.utils.io.core.Input +import kotlinx.io.Source +import kotlinx.io.asInputStream import space.kscience.dataforge.io.IOReader import java.awt.image.BufferedImage import javax.imageio.ImageIO @@ -11,5 +12,5 @@ import kotlin.reflect.typeOf internal object ImageIOReader : IOReader { override val type: KType get() = typeOf() - override fun readObject(input: Input): BufferedImage = ImageIO.read(input.asStream()) + override fun readFrom(source: Source): BufferedImage = ImageIO.read(source.asInputStream()) } \ No newline at end of file diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/SiteLayout.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/SiteLayout.kt index ed8712b..807422d 100644 --- a/snark-html/src/main/kotlin/space/kscience/snark/html/SiteLayout.kt +++ b/snark-html/src/main/kotlin/space/kscience/snark/html/SiteLayout.kt @@ -1,13 +1,13 @@ package space.kscience.snark.html import space.kscience.dataforge.data.DataTreeItem -import space.kscience.dataforge.misc.Type +import space.kscience.dataforge.misc.DfId import space.kscience.dataforge.names.NameToken /** * An abstraction to render singular data or a data tree. */ -@Type(SiteLayout.TYPE) +@DfId(SiteLayout.TYPE) public fun interface SiteLayout { context(SiteBuilder) diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/SnarkHtmlPlugin.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/SnarkHtmlPlugin.kt index f7cf6bf..621b01a 100644 --- a/snark-html/src/main/kotlin/space/kscience/snark/html/SnarkHtmlPlugin.kt +++ b/snark-html/src/main/kotlin/space/kscience/snark/html/SnarkHtmlPlugin.kt @@ -1,6 +1,7 @@ package space.kscience.snark.html import io.ktor.utils.io.core.readBytes +import kotlinx.io.readByteArray import space.kscience.dataforge.context.* import space.kscience.dataforge.data.DataTree import space.kscience.dataforge.data.node @@ -83,7 +84,7 @@ public class SnarkHtmlPlugin : AbstractPlugin() { override fun build(context: Context, meta: Meta): SnarkHtmlPlugin = SnarkHtmlPlugin() private val byteArrayIOReader = IOReader { - readBytes() + readByteArray() } internal val byteArraySnarkParser = SnarkParser(byteArrayIOReader) diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/StaticSiteBuilder.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/StaticSiteBuilder.kt index 63d0224..e6fef23 100644 --- a/snark-html/src/main/kotlin/space/kscience/snark/html/StaticSiteBuilder.kt +++ b/snark-html/src/main/kotlin/space/kscience/snark/html/StaticSiteBuilder.kt @@ -1,17 +1,16 @@ package space.kscience.snark.html -import io.ktor.utils.io.streams.asInput -import io.ktor.utils.io.streams.asOutput import kotlinx.coroutines.runBlocking import kotlinx.html.HTML import kotlinx.html.html import kotlinx.html.stream.createHTML +import kotlinx.io.asSink +import kotlinx.io.buffered import space.kscience.dataforge.data.DataTree import space.kscience.dataforge.data.DataTreeItem import space.kscience.dataforge.data.await import space.kscience.dataforge.data.getItem import space.kscience.dataforge.io.Binary -import space.kscience.dataforge.io.toByteArray import space.kscience.dataforge.io.writeBinary import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name @@ -66,7 +65,7 @@ internal class StaticSiteBuilder( if (datum.type != typeOf()) error("Can't directly serve file of type ${item.data.type}") val targetPath = outputPath.resolve(routeName.toWebPath()) val binary = datum.await() as Binary - targetPath.outputStream().asOutput().use{ + targetPath.outputStream().asSink().buffered().use { it.writeBinary(binary) } } diff --git a/snark-html/src/main/kotlin/space/kscience/snark/html/TextProcessor.kt b/snark-html/src/main/kotlin/space/kscience/snark/html/TextProcessor.kt index d8b44eb..16e49c8 100644 --- a/snark-html/src/main/kotlin/space/kscience/snark/html/TextProcessor.kt +++ b/snark-html/src/main/kotlin/space/kscience/snark/html/TextProcessor.kt @@ -1,15 +1,14 @@ package space.kscience.snark.html -import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.string -import space.kscience.dataforge.misc.Type +import space.kscience.dataforge.misc.DfId import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.parseAsName /** * An object that conducts page-based text transformation. Like using link replacement or templating. */ -@Type(TextProcessor.TYPE) +@DfId(TextProcessor.TYPE) public fun interface TextProcessor { context(WebPage) public fun process(text: String): String diff --git a/snark-pandoc/src/jvmMain/kotlin/space/kscience/snark/pandoc/Pandoc.kt b/snark-pandoc/src/jvmMain/kotlin/space/kscience/snark/pandoc/Pandoc.kt index 7a0592d..609ebbe 100644 --- a/snark-pandoc/src/jvmMain/kotlin/space/kscience/snark/pandoc/Pandoc.kt +++ b/snark-pandoc/src/jvmMain/kotlin/space/kscience/snark/pandoc/Pandoc.kt @@ -2,12 +2,9 @@ package space.kscience.snark.pandoc import org.slf4j.Logger import org.slf4j.LoggerFactory -import java.io.BufferedReader import java.io.IOException -import java.io.InputStreamReader import java.nio.file.Files import java.nio.file.Path -import java.nio.file.StandardOpenOption import java.util.concurrent.TimeUnit import kotlin.io.path.Path @@ -36,34 +33,24 @@ public object Pandoc { redirectError: Path? = null, pandocExecutablePath: Path = Path("./pandoc").toAbsolutePath(), commandBuilder: PandocCommandBuilder.() -> Unit, - ): Boolean { + ) { val path = getOrInstallPandoc(pandocExecutablePath) - try { - val commandLine = PandocCommandBuilder().apply(commandBuilder).build(path) - logger.info("Running pandoc: ${commandLine.joinToString(separator = " ")}") - val pandoc = ProcessBuilder(commandLine).apply { - if(redirectOutput!= null){ - redirectOutput(redirectOutput.toFile()) - } - if(redirectError !=null){ - redirectError(redirectError.toFile()) - } - - }.start() - pandoc.waitFor(1, TimeUnit.SECONDS) - - if (pandoc.exitValue() == 0) { - logger.info("Successfully execute") - return true - } else{ - return false + val commandLine = PandocCommandBuilder().apply(commandBuilder).build(path) + logger.info("Running pandoc: ${commandLine.joinToString(separator = " ")}") + val pandoc = ProcessBuilder(commandLine).apply { + if (redirectOutput != null) { + redirectOutput(redirectOutput.toFile()) + } + if (redirectError != null) { + redirectError(redirectError.toFile()) } - } catch (e: Exception) { - logger.error("Got problems with executing: " + e.message) - return false - } - } + }.start() + pandoc.waitFor() + + if (pandoc.exitValue() != 0) + error("Non-zero process return for pandoc.") + } } diff --git a/snark-pandoc/src/jvmMain/kotlin/space/kscience/snark/pandoc/PandocInstaller.kt b/snark-pandoc/src/jvmMain/kotlin/space/kscience/snark/pandoc/PandocInstaller.kt index 0c7eea0..0187857 100644 --- a/snark-pandoc/src/jvmMain/kotlin/space/kscience/snark/pandoc/PandocInstaller.kt +++ b/snark-pandoc/src/jvmMain/kotlin/space/kscience/snark/pandoc/PandocInstaller.kt @@ -31,7 +31,7 @@ internal object PandocInstaller { private const val TIMEOUT_SECONDS = 2 private const val ATTEMPTS = 3 - private enum class OSType(public val assetSuffix: String, public val propertySuffix: String) { + private enum class OSType(val assetSuffix: String, val propertySuffix: String) { WINDOWS("windows-x86_64.zip", "windows"), MAC_OS_AMD("x86_64-macOS.zip", "mac.os.amd"), MAC_OS_ARM("arm64-macOS.zip", "mac.os.arm"), diff --git a/snark-pandoc/src/jvmTest/kotlin/PandocTest.kt b/snark-pandoc/src/jvmTest/kotlin/PandocTest.kt index f61b0d9..6c48f6e 100644 --- a/snark-pandoc/src/jvmTest/kotlin/PandocTest.kt +++ b/snark-pandoc/src/jvmTest/kotlin/PandocTest.kt @@ -1,96 +1,97 @@ -import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import space.kscience.snark.pandoc.Pandoc -import java.io.BufferedReader -import java.io.FileReader -import java.io.IOException import java.nio.file.Files import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.Path -import kotlin.io.path.createDirectories -import kotlin.io.path.div +import kotlin.io.path.exists +import kotlin.io.path.isDirectory +import kotlin.io.path.readText +import kotlin.io.path.writeBytes +import kotlin.test.assertContains +import kotlin.test.assertFails class PandocTest { @Test fun when_gotPandocAndCorrectArgs_doConverting() { - try { - val res = Pandoc.execute { - addInputFile(CORRECT_MD) - outputFile(TEX_PATH_TO) - } - assertTrue(res) - assertTrue(TEX_PATH_TO.toFile().exists()) - val reader = BufferedReader(FileReader(TEX_PATH_TO.toFile())) - val fileString = reader.lines().collect(Collectors.joining()) + val inputFile = Files.createTempFile("snark-pandoc", "first_test.md") + inputFile.writeBytes(javaClass.getResourceAsStream("/first_test.md")!!.readAllBytes()) + val outputFile = Files.createTempFile("snark-pandoc", "output1.tex") - assertTrue(fileString.contains("Some simple text")) - assertTrue(fileString.contains("\\subsection{Copy elision}")) - assertTrue(fileString.contains("return")) - - Files.delete(TEX_PATH_TO) - } catch (ex: Exception) { - fail("Unexpected exception during test when_gotPandocAndCorrectArgs_doConverting()", ex) + Pandoc.execute { + addInputFile(inputFile) + outputFile(outputFile) } + + assertTrue(outputFile.exists()) + + val result = outputFile.readText() + + assertContains(result, "Some simple text") + assertContains(result, "\\subsection{Copy elision}") + assertContains(result, "return") } @Test fun when_gotPandocAndNotExistsFromFile_then_error() { + + val outputFile = Files.createTempFile("snark-pandoc", "output2.tex") val notExistsFile = Path.of("./src/test/testing_directory/non_exists_test.md") - assertFalse(notExistsFile.toFile().exists()) - val res = Pandoc.execute { - addInputFile(notExistsFile) - outputFile(TEX_PATH_TO) + assertFalse(notExistsFile.exists()) + assertFails { + Pandoc.execute { + addInputFile(notExistsFile) + outputFile(outputFile) + } } - assertFalse(res) } @Test fun when_gotPandocAndPassDirectory_then_error() { - assertTrue(TESTING_DIRECTORY.toFile().isDirectory) + val tempDir = Files.createTempDirectory("snark-pandoc") + assertTrue(tempDir.isDirectory()) - val res = Pandoc.execute { - addInputFile(TESTING_DIRECTORY) - outputFile(TEX_PATH_TO) + val outputFile = Files.createTempFile("snark-pandoc", "output3.tex") + + assertFails { + Pandoc.execute { + addInputFile(tempDir) + outputFile(outputFile) + } } - assertFalse(res) } @Test fun when_askVersionToFile_then_Ok() { - val outputFile = TESTING_DIRECTORY/"output.txt" + val outputFile = Files.createTempFile("snark-pandoc", "output4.tex") val res = Pandoc.execute(redirectOutput = outputFile) { getVersion() } - val reader = BufferedReader(FileReader(outputFile.toFile())) - val fileString = reader.lines().collect(Collectors.joining()) - assertTrue(fileString.contains("pandoc")) - assertTrue(fileString.contains("This is free software")) - assertTrue(res) + val fileContent = outputFile.readText() + assertContains(fileContent, "pandoc") + assertContains(fileContent, "This is free software") } @Test fun when_error_then_writeToErrorStream() { - val outputFile = Files.createTempFile(TESTING_DIRECTORY, "output", ".txt") - val errorFile = Files.createTempFile(TESTING_DIRECTORY, "error", ".txt") + val inputFile = Files.createTempFile("snark-pandoc", "simple.txt") + inputFile.writeBytes(javaClass.getResourceAsStream("/simple.txt")!!.readAllBytes()) + val outputFile = Files.createTempFile("snark-pandoc", "output.txt") + val errorFile = Files.createTempFile("snark-pandoc", "error.txt") - val res = Pandoc.execute(outputFile, errorFile) { - addInputFile(Path.of("./simple.txt")) - outputFile(TEX_PATH_TO) - formatFrom("txt") + assertFails { + Pandoc.execute(redirectError = errorFile) { + addInputFile(inputFile) + outputFile(outputFile) + formatFrom("txt") + } } - val reader = BufferedReader(FileReader(errorFile.toFile())) - val fileString = reader.lines().collect(Collectors.joining()) - assertFalse(res) - assertTrue(fileString.contains("21")) - - Files.delete(outputFile) - Files.delete(errorFile) + assertContains(errorFile.readText(), "input format") } @@ -101,11 +102,4 @@ class PandocTest { // assertTrue(Pandoc.isPandocInstalled()) // } - companion object { - private val TESTING_DIRECTORY: Path = Path("./testing_directory").apply { - createDirectories() - } - private val CORRECT_MD: Path = TESTING_DIRECTORY.resolve("first_test.md") - private val TEX_PATH_TO: Path = TESTING_DIRECTORY.resolve("output1.tex") - } } diff --git a/snark-pandoc/testing_directory/first_test.md b/snark-pandoc/src/jvmTest/resources/first_test.md similarity index 100% rename from snark-pandoc/testing_directory/first_test.md rename to snark-pandoc/src/jvmTest/resources/first_test.md diff --git a/snark-pandoc/testing_directory/simple.txt b/snark-pandoc/src/jvmTest/resources/simple.txt similarity index 100% rename from snark-pandoc/testing_directory/simple.txt rename to snark-pandoc/src/jvmTest/resources/simple.txt