Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ abstract class GenerateSnapshotTestsTask : DefaultTask() {
package $PACKAGE_NAME

import android.content.res.Configuration.UI_MODE_NIGHT_MASK
import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
Expand Down Expand Up @@ -357,23 +358,32 @@ class $CLASS_NAME(
val imagesDir = File(snapshotDir, "images")
imagesDir.mkdirs()
val info = preview.previewInfo
val metadata = linkedMapOf<String, Any>(
"display_name" to screenshotId.removePrefix(preview.declaringClass + "."),

val tags = linkedMapOf<String, Any>()
if (info.name.isNotBlank()) tags["preview_name"] = info.name
if (info.locale.isNotBlank()) tags["locale"] = info.locale
if (info.device.isNotBlank()) tags["device"] = info.device
if (info.fontScale != 1f) tags["font_scale"] = info.fontScale
if (info.apiLevel != -1) tags["api_level"] = info.apiLevel
if (info.widthDp > 0) tags["width_dp"] = info.widthDp
if (info.heightDp > 0) tags["height_dp"] = info.heightDp
if (info.showSystemUi) tags["show_system_ui"] = true
if (info.showBackground) tags["show_background"] = true
when (info.uiMode and UI_MODE_NIGHT_MASK) {
UI_MODE_NIGHT_YES -> tags["ui_mode"] = "dark"
UI_MODE_NIGHT_NO -> tags["ui_mode"] = "light"
}
Comment thread
runningcode marked this conversation as resolved.

val context = linkedMapOf<String, Any>(
"image_file_name" to screenshotId,
"class_name" to preview.declaringClass,
"method_name" to preview.methodName,
)

val metadata = linkedMapOf<String, Any>(
"display_name" to screenshotId.removePrefix(preview.declaringClass + "."),
)
if (info.group.isNotBlank()) metadata["group"] = info.group
if (info.name.isNotBlank()) metadata["preview_name"] = info.name
if (info.locale.isNotBlank()) metadata["locale"] = info.locale
if (info.device.isNotBlank()) metadata["device"] = info.device
metadata["night_mode"] = (info.uiMode and UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES)
if (info.fontScale != 1f) metadata["font_scale"] = info.fontScale
if (info.apiLevel != -1) metadata["api_level"] = info.apiLevel
if (info.widthDp > 0) metadata["width_dp"] = info.widthDp
if (info.heightDp > 0) metadata["height_dp"] = info.heightDp
if (info.showSystemUi) metadata["show_system_ui"] = true
if (info.showBackground) metadata["show_background"] = true

val diffThreshold: Float? = runCatching {
val declaring = Class.forName(preview.declaringClass)
Expand All @@ -386,15 +396,33 @@ class $CLASS_NAME(
}.getOrNull()
if (diffThreshold != null && diffThreshold != 0f) metadata["diff_threshold"] = diffThreshold

val json = metadata.entries.joinToString(",\n ", prefix = "{\n ", postfix = "\n}") { (k, v) ->
if (v is String) "\"" + k + "\": \"" + escapeJson(v) + "\""
else "\"" + k + "\": " + v
}
if (tags.isNotEmpty()) metadata["tags"] = tags
metadata["context"] = context

val json = renderJson(metadata, 0)
val sidecarName = "Paparazzi_Preview_Test_" +
screenshotId.lowercase(Locale.US).replace("\\s".toRegex(), "_")
File(imagesDir, "${'$'}{sidecarName}.json").writeText(json)
}

private fun renderJson(value: Any, indentLevel: Int): String {
val indent = " ".repeat(indentLevel)
val childIndent = " ".repeat(indentLevel + 1)
return when (value) {
is String -> "\"" + escapeJson(value) + "\""
is Boolean, is Number -> value.toString()
is Map<*, *> -> when (value.isEmpty()) {
true -> "{}"
false -> value.entries.joinToString(
separator = ",\n${'$'}childIndent",
prefix = "{\n${'$'}childIndent",
postfix = "\n${'$'}indent}",
) { (k, v) -> "\"${'$'}k\": " + renderJson(v!!, indentLevel + 1) }
}
else -> "\"" + escapeJson(value.toString()) + "\""
}
}

private fun escapeJson(s: String): String =
s.replace("\\", "\\\\").replace("\"", "\\\"")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,50 @@ class GenerateSnapshotTestsTaskTest {
)
}

@Test
fun `generated sidecar places preview location fields in context block`() {
val content = generateAndRead(packageTrees = listOf("com.example"))

assertTrue(content.contains("val context = linkedMapOf<String, Any>("))
assertTrue(content.contains("\"image_file_name\" to screenshotId"))
assertTrue(content.contains("\"class_name\" to preview.declaringClass"))
assertTrue(content.contains("\"method_name\" to preview.methodName"))
assertTrue(content.contains("metadata[\"context\"] = context"))
}

@Test
fun `generated sidecar places appearance inputs in tags block`() {
val content = generateAndRead(packageTrees = listOf("com.example"))

assertTrue(content.contains("val tags = linkedMapOf<String, Any>()"))
assertTrue(content.contains("if (info.name.isNotBlank()) tags[\"preview_name\"] = info.name"))
assertTrue(content.contains("if (info.locale.isNotBlank()) tags[\"locale\"] = info.locale"))
assertTrue(content.contains("if (info.device.isNotBlank()) tags[\"device\"] = info.device"))
assertTrue(content.contains("if (info.fontScale != 1f) tags[\"font_scale\"] = info.fontScale"))
assertTrue(content.contains("if (info.apiLevel != -1) tags[\"api_level\"] = info.apiLevel"))
assertTrue(content.contains("if (info.widthDp > 0) tags[\"width_dp\"] = info.widthDp"))
assertTrue(content.contains("if (info.heightDp > 0) tags[\"height_dp\"] = info.heightDp"))
assertTrue(content.contains("if (info.showSystemUi) tags[\"show_system_ui\"] = true"))
assertTrue(content.contains("if (info.showBackground) tags[\"show_background\"] = true"))
assertTrue(content.contains("if (tags.isNotEmpty()) metadata[\"tags\"] = tags"))
}

@Test
fun `generated sidecar places ui_mode in tags block`() {
val content = generateAndRead(packageTrees = listOf("com.example"))

assertTrue(content.contains("when (info.uiMode and UI_MODE_NIGHT_MASK) {"))
assertTrue(content.contains("UI_MODE_NIGHT_YES -> tags[\"ui_mode\"] = \"dark\""))
assertTrue(content.contains("UI_MODE_NIGHT_NO -> tags[\"ui_mode\"] = \"light\""))
}

@Test
fun `generated sidecar does not emit legacy night_mode field`() {
val content = generateAndRead(packageTrees = listOf("com.example"))

assertFalse(content.contains("metadata[\"night_mode\"]"))
}

@Test
fun `parseMajorVersion extracts major from standard semver`() {
assertEquals(1, parseMajorVersion("1.3.5"))
Expand Down
Loading