From a73063ff54250144e417b82991a41bf054413214 Mon Sep 17 00:00:00 2001 From: Giorgio Garofalo Date: Sat, 31 Aug 2024 00:36:21 +0200 Subject: [PATCH] Add resource exportation test --- .../pipeline/output/LazyOutputArtifact.kt | 5 +- .../kotlin/eu/iamgio/quarkdown/MiscTest.kt | 101 +++++++++++++++++- 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/pipeline/output/LazyOutputArtifact.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/pipeline/output/LazyOutputArtifact.kt index 1522ac10..c25d2874 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/pipeline/output/LazyOutputArtifact.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/pipeline/output/LazyOutputArtifact.kt @@ -1,6 +1,7 @@ package eu.iamgio.quarkdown.pipeline.output import eu.iamgio.quarkdown.pipeline.error.IOPipelineException +import kotlin.reflect.KClass /** * Represents a [BinaryOutputArtifact] whose content is lazily loaded on demand (via [accept]). @@ -22,15 +23,17 @@ data class LazyOutputArtifact( * @param resource path to the internal resource * @param name name of the resource (without file extensions) * @param type type of content the resource contains + * @param referenceClass reference classpath to use to retrieve the internal resource */ fun internal( resource: String, name: String, type: ArtifactType, + referenceClass: KClass<*> = LazyOutputArtifact::class, ) = LazyOutputArtifact( name, content = { - LazyOutputArtifact::class.java.getResource(resource) + referenceClass.java.getResource(resource) ?.readBytes() ?: throw IOPipelineException("Resource $resource not found") }, diff --git a/core/src/test/kotlin/eu/iamgio/quarkdown/MiscTest.kt b/core/src/test/kotlin/eu/iamgio/quarkdown/MiscTest.kt index 77f86a45..c69863be 100644 --- a/core/src/test/kotlin/eu/iamgio/quarkdown/MiscTest.kt +++ b/core/src/test/kotlin/eu/iamgio/quarkdown/MiscTest.kt @@ -15,15 +15,23 @@ import eu.iamgio.quarkdown.context.MutableContext import eu.iamgio.quarkdown.context.toc.TableOfContents import eu.iamgio.quarkdown.document.locale.JVMLocaleLoader import eu.iamgio.quarkdown.flavor.quarkdown.QuarkdownFlavor +import eu.iamgio.quarkdown.pipeline.output.ArtifactType +import eu.iamgio.quarkdown.pipeline.output.BinaryOutputArtifact +import eu.iamgio.quarkdown.pipeline.output.FileResourceExporter +import eu.iamgio.quarkdown.pipeline.output.LazyOutputArtifact +import eu.iamgio.quarkdown.pipeline.output.OutputResourceGroup +import eu.iamgio.quarkdown.pipeline.output.TextOutputArtifact import eu.iamgio.quarkdown.rendering.html.HtmlIdentifierProvider import eu.iamgio.quarkdown.rendering.html.QuarkdownHtmlNodeRenderer import eu.iamgio.quarkdown.util.flattenedChildren -import org.junit.Assert.assertEquals -import org.junit.Assert.assertTrue +import java.nio.file.Files import kotlin.test.Test +import kotlin.test.assertContentEquals +import kotlin.test.assertEquals import kotlin.test.assertIs import kotlin.test.assertNotNull import kotlin.test.assertNull +import kotlin.test.assertTrue /** * Tests for miscellaneous classes. @@ -221,4 +229,93 @@ class MiscTest { assertTrue(retriever.all.iterator().hasNext()) } + + @Test + fun `resource export`() { + val dir = Files.createTempDirectory("quarkdown-resource-test") + val exporter = FileResourceExporter(dir.toFile()) + + with("Hello, world!".repeat(1000)) { + assertEquals( + this, + TextOutputArtifact("Artifact 1", this, ArtifactType.HTML) + .accept(exporter) + .also { assertEquals("Artifact-1.html", it.name) } + .readText(), + ) + assertContentEquals( + this.toByteArray(), + BinaryOutputArtifact("a/rt*fact::2", this.toByteArray(), ArtifactType.JAVASCRIPT) + .accept(exporter) + .also { assertEquals("a-rt-fact-2.js", it.name) } + .readBytes(), + ) + } + + with("Quarkdown".repeat(1000)) { + LazyOutputArtifact("artifact3", { this.toByteArray() }, ArtifactType.CSS) + .accept(exporter) + .also { assertEquals("artifact3.css", it.name) } + .let { file -> + assertEquals(this, file.readText()) + assertContentEquals(this.toByteArray(), file.readBytes()) + } + } + + LazyOutputArtifact.internal( + resource = "/media/icon.png", + name = "artif@ct 4.png", + type = ArtifactType.AUTO, + referenceClass = this::class, + ).run { + assertContentEquals( + this::class.java.getResourceAsStream("/media/icon.png")!!.readBytes(), + this.accept(exporter) + .also { assertEquals("artif@ct-4.png", it.name) } + .readBytes(), + ) + } + + val group = + OutputResourceGroup( + "Group 1", + setOf( + TextOutputArtifact("Artifact 5", "Hello, world!", ArtifactType.HTML), + BinaryOutputArtifact("arti-fact6", "Quarkdown".toByteArray(), ArtifactType.JAVASCRIPT), + LazyOutputArtifact("artifact7", { "Quarkdown".toByteArray() }, ArtifactType.CSS), + OutputResourceGroup( + "Group 2", + setOf( + TextOutputArtifact("Artifact 8", "Hello, world!", ArtifactType.HTML), + BinaryOutputArtifact("art*fact/9", "Quarkdown".toByteArray(), ArtifactType.JAVASCRIPT), + ), + ), + LazyOutputArtifact.internal( + referenceClass = this::class, + resource = "/media/banner.png", + name = "artif@ct 10.png", + type = ArtifactType.AUTO, + ), + BinaryOutputArtifact("artifact11", "Hello world".repeat(100).toByteArray(), ArtifactType.JAVASCRIPT), + ), + ) + + val groupFile = group.accept(exporter) + + assertTrue(groupFile.isDirectory) + val files = groupFile.listFiles()!! + assertEquals(6, files.size) + + assertEquals(1, files.count { it.extension == "html" }) + assertEquals(2, files.count { it.extension == "js" }) + assertEquals(1, files.count { it.extension == "css" }) + assertEquals(1, files.count { it.extension == "png" }) + + val subGroup = files.single { it.isDirectory } + subGroup.listFiles()!!.let { subFiles -> + assertEquals(2, subFiles.size) + assertEquals(1, subFiles.count { it.extension == "html" }) + assertEquals(1, subFiles.count { it.extension == "js" }) + } + } }