Skip to content

Commit

Permalink
cleanup and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskn committed Sep 29, 2024
1 parent bd132ea commit c3e04c7
Show file tree
Hide file tree
Showing 16 changed files with 414 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ fun createElementStyle(
legendText: String? = null,
legendSprite: Sprite? = null,
): ElementStyle {
require(tag.isNotBlank()) { "tag cannot be blank" }
val style = createElementStyleFromTag(tag)
style.backgroundColor = backgroundColor
style.fontColor = fontColor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ fun ViewSet.addElementStyle(elementStyle: ElementStyle) {

fun ViewSet.getElementStyles(): List<ElementStyle> =
this.configuration.styles.elements.toList()

internal fun ViewSet.clearElementStyles() {
this.configuration.styles.elements.clear()
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@ fun View.addElementStyle(elementStyle: ElementStyle) {

fun View.getElementStyles(): List<ElementStyle> =
this.properties
.filterKeys { it.startsWith(ELEMENT_STYLE_PROPERTY_NAME_PREFIX) }
.values
.map { elementStyleFromJson(it) }
.filter { it.key.startsWith(ELEMENT_STYLE_PROPERTY_NAME_PREFIX) }
.map { elementStyleFromJson(it.value) }
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
package com.github.chriskn.structurizrextension.api.view.style.sprite

import java.net.URI

private val fileInUriRegex = "[^/\\\\&?]+\\.\\w{3,4}(?=([?&].*\$|\$))".toRegex()

data class ImageSprite(
val url: String,
override val scale: Double? = null,
) : Sprite
val scale: Double? = null,
) : Sprite(scale) {

init {
validateImageUrl(url)
}

private fun validateImageUrl(urlString: String) {
val uri = URI(urlString)
val mathResult = fileInUriRegex.find(uri.schemeSpecificPart)
val fileWithEnding = mathResult?.groupValues?.first()
require(fileWithEnding?.contains(".") == true) {
"Image URI must point to a file"
}
require(uri.scheme == "img") { "Image URI must use img scheme" }
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package com.github.chriskn.structurizrextension.api.view.style.sprite

import com.fasterxml.jackson.annotation.JsonIgnore
import com.github.chriskn.structurizrextension.api.view.style.toValidColor

data class OpenIconicSprite(
val name: String,
val color: String? = null,
override val scale: Double? = null,
) : Sprite
val scale: Double? = null,
) : Sprite(scale) {

@get:JsonIgnore
internal val validatedColor: String? = color?.let { toValidColor(color) }
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package com.github.chriskn.structurizrextension.api.view.style.sprite

import com.fasterxml.jackson.annotation.JsonIgnore
import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.style.toValidColor
import java.net.MalformedURLException

data class PumlSprite(
val name: String,
/**
* Url used for include statement
*
* @throws IllegalArgumentException if url does not point to puml file
* @throws MalformedURLException if url is invalid
*/
val includeUrl: String,
val name: String,
val color: String? = null,
override val scale: Double? = null,
) : Sprite {
val scale: Double? = null,
) : Sprite(scale) {

@get:JsonIgnore
internal val validatedColor: String? = color?.let { toValidColor(color) }

init {
require(name.isNotBlank()) { "name cannot be blank" }
// TODO is the registry still needed?
IconRegistry.addIcon(name, includeUrl)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo
Type(value = PumlSprite::class, name = "PumlSprite"),
]
)
interface Sprite {
abstract class Sprite(scale: Double?) {

val scale: Double?
init {
require((scale ?: 1.0) > 0.0) {
"Scale must be greater than zero."
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ internal object ElementStyleWriter {
.configuration
.styles
.elements
.filter { usedTags.contains(it.tag) } + view.getElementStyles()
return stylesForTags
.filter { usedTags.contains(it.tag) } +
view
.getElementStyles()
.filter { usedTags.contains(it.tag) }
return stylesForTags.distinctBy { it.tag }
}

fun writeElementStyle(elementStyle: ElementStyle, writer: IndentingWriter) {
Expand Down Expand Up @@ -92,8 +95,8 @@ internal object ElementStyleWriter {
}

private fun Sprite.toPlantUmlString(): String = when (this) {
is PumlSprite -> """"${spriteString(this.name, scale, color)}""""
is OpenIconicSprite -> """"&${spriteString(this.name, scale, color)}""""
is PumlSprite -> """"${spriteString(this.name, scale, validatedColor)}""""
is OpenIconicSprite -> """"&${spriteString(this.name, scale, validatedColor)}""""
is ImageSprite -> {
val scaleString = scaleString(this.scale)
if (scaleString.isBlank()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,108 +1,119 @@
// package com.github.chriskn.structurizrextension.view.sprite
//
// import com.github.chriskn.structurizrextension.api.view.style.createElementStyle
// import com.github.chriskn.structurizrextension.api.view.style.sprite
// import org.assertj.core.api.Assertions.assertThat
// import org.junit.jupiter.api.Test
// import org.junit.jupiter.api.assertThrows
//
// class SpriteTest {
//
// @Test
// fun `sprite is serialized and deserialized correctly when URI with scale is used`() {
// val expectedSprite = SpriteOld(URI.create("img:https://plantuml.com/logo.png"), 0.4)
// val style = createElementStyle("test", sprite = expectedSprite)
//
// assertThat(style.sprite).isEqualTo(expectedSprite)
// }
//
// @Test
// fun `sprite is serialized and deserialized correctly when URI without scale is used`() {
// val expectedSprite = SpriteOld(URI.create("img:https://plantuml.com/logo.png"))
// val style = createElementStyle("test", sprite = expectedSprite)
//
// assertThat(style.sprite).isEqualTo(expectedSprite)
// }
//
// @Test
// fun `sprite is serialized and deserialized correctly when openIconicIcon with scale is used`() {
// val expectedSprite = SpriteOld("folder", scale = 0.4)
// val style = createElementStyle("test", sprite = expectedSprite)
//
// assertThat(style.sprite).isEqualTo(expectedSprite)
// }
//
// @Test
// fun `sprite is serialized and deserialized correctly when openIconicIcon with color is used`() {
// val expectedSprite = SpriteOld("folder", color = "grey")
// val style = createElementStyle("test", sprite = expectedSprite)
//
// assertThat(style.sprite).isEqualTo(expectedSprite)
// }
//
// @Test
// fun `sprite is serialized and deserialized correctly when openIconicIcon with scale and color is used`() {
// val expectedSprite = SpriteOld("folder", color = "grey", scale = 0.1)
// val style = createElementStyle("test", sprite = expectedSprite)
//
// assertThat(style.sprite).isEqualTo(expectedSprite)
// }
//
// @Test
// fun `sprite is serialized and deserialized correctly when openIconicIcon without scale and color is used`() {
// val expectedSprite = SpriteOld("folder")
// val style = createElementStyle("test", sprite = expectedSprite)
//
// assertThat(style.sprite).isEqualTo(expectedSprite)
// }
//
// @Test
// fun `IllegalArgumentException is thrown when uri without image schema is used`() {
// assertThrows<IllegalArgumentException> {
// SpriteOld(URI.create("https://plantuml.com/logo.png"))
// }
// }
//
// @Test
// fun `IllegalArgumentException is thrown when uri with different schema is used`() {
// assertThrows<IllegalArgumentException> {
// SpriteOld(URI.create("file:https://plantuml.com/logo.png"))
// }
// }
//
// @Test
// fun `IllegalArgumentException is thrown when uri is not absolute`() {
// assertThrows<IllegalArgumentException> {
// SpriteOld(URI.create("img:https://plantuml.com/"))
// }
// }
//
// @Test
// fun `IllegalArgumentException is thrown if scale is negative `() {
// assertThrows<IllegalArgumentException> {
// SpriteOld(URI.create("img:https://plantuml.com//logo.png"), -0.1)
// }
// }
//
// @Test
// fun `IllegalArgumentException is thrown if scale is zero `() {
// assertThrows<IllegalArgumentException> {
// SpriteOld(URI.create("img:https://plantuml.com//logo.png"), 0.0)
// }
// }
//
// @Test
// fun `sprite is serialized and deserialized correctly when openIconicIcon is used`() {
// val expectedSprite = SpriteOld("iconName", 0.4)
// val style = createElementStyle("test", sprite = expectedSprite)
//
// assertThat(style.sprite).isEqualTo(expectedSprite)
// }
//
// @Test
// fun `IllegalArgumentException is thrown for invalid sprite color color`() {
// assertThrows<IllegalArgumentException> {
// SpriteOld("folder", color = "123")
// }
// }
// }
package com.github.chriskn.structurizrextension.view.sprite

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.style.sprite.ImageSprite
import com.github.chriskn.structurizrextension.api.view.style.sprite.OpenIconicSprite
import com.github.chriskn.structurizrextension.api.view.style.sprite.PumlSprite
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows

class SpriteTest {

@Nested
inner class ImageSpriteTest {

@Test
fun `IllegalArgumentException is thrown when uri does not point to file`() {
assertThrows<IllegalArgumentException> {
ImageSprite("https://plantuml.com/logo")
}
}

@Test
fun `IllegalArgumentException is thrown when uri without image schema is used`() {
assertThrows<IllegalArgumentException> {
ImageSprite("https://plantuml.com/logo.png")
}
}

@Test
fun `IllegalArgumentException is thrown when uri with different schema is used`() {
assertThrows<IllegalArgumentException> {
ImageSprite("file:https://plantuml.com/logo.png")
}
}

@Test
fun `IllegalArgumentException is thrown if scale is negative `() {
assertThrows<IllegalArgumentException> {
ImageSprite("img:https://plantuml.com/logo.png", -0.1)
}
}

@Test
fun `IllegalArgumentException is thrown if scale is zero `() {
assertThrows<IllegalArgumentException> {
ImageSprite("img:https://plantuml.com/logo.png", 0.0)
}
}
}

@Nested
inner class OpenIconicSpriteTest {

@Test
fun `IllegalArgumentException is thrown for invalid OpenIconicSprite color`() {
assertThrows<IllegalArgumentException> {
OpenIconicSprite("folder", color = "123")
}
}
}

@Nested
inner class PumlSpriteTest {

@Test
fun `IllegalArgumentException is thrown when name is blank`() {
val url = IconRegistry.iconUrlFor("kafka")!!
assertThrows<IllegalArgumentException> {
PumlSprite(name = "", includeUrl = url)
}
}

@Test
fun `IllegalArgumentException is thrown when url is blank`() {
assertThrows<IllegalArgumentException> {
PumlSprite(name = " ", includeUrl = " ")
}
}

@Test
fun `IllegalArgumentException is thrown for invalid PumlSprite color`() {
val name = IconRegistry.iconFileNameFor("kafka")!!
val url = IconRegistry.iconUrlFor("kafka")!!

assertThrows<IllegalArgumentException> {
PumlSprite(name = name, includeUrl = url, color = "123")
}
}

@Test
fun `IllegalArgumentException is thrown when url does not point to a puml file`() {
assertThrows<IllegalArgumentException> {
PumlSprite("test", "https://plantuml.com/logo.png")
}
}

@Test
fun `IllegalArgumentException is thrown when url is invalid`() {
assertThrows<IllegalArgumentException> {
PumlSprite("test", "plantuml.com/logo.png")
}
}

@Test
fun `IllegalArgumentException is thrown if scale is negative `() {
assertThrows<IllegalArgumentException> {
PumlSprite("test", "https://plantuml.com/logo.puml", scale = -0.1)
}
}

@Test
fun `IllegalArgumentException is thrown if scale is zero `() {
assertThrows<IllegalArgumentException> {
PumlSprite("test", "https://plantuml.com/logo.puml", scale = 0.0)
}
}
}
}
Loading

0 comments on commit c3e04c7

Please sign in to comment.