@@ -104,6 +104,7 @@ abstract class GenerateSnapshotTestsTask : DefaultTask() {
104104package $PACKAGE_NAME
105105
106106import android.content.res.Configuration.UI_MODE_NIGHT_MASK
107+ import android.content.res.Configuration.UI_MODE_NIGHT_NO
107108import android.content.res.Configuration.UI_MODE_NIGHT_YES
108109import androidx.compose.foundation.background
109110import androidx.compose.foundation.layout.Box
@@ -357,23 +358,33 @@ class $CLASS_NAME(
357358 val imagesDir = File(snapshotDir, "images")
358359 imagesDir.mkdirs()
359360 val info = preview.previewInfo
360- val metadata = linkedMapOf<String, Any>(
361- "display_name" to screenshotId.removePrefix(preview.declaringClass + "."),
361+
362+ val tags = linkedMapOf<String, Any>()
363+ if (info.name.isNotBlank()) tags["preview_name"] = info.name
364+ if (info.locale.isNotBlank()) tags["locale"] = info.locale
365+ if (info.device.isNotBlank()) tags["device"] = info.device
366+ if (info.fontScale != 1f) tags["font_scale"] = info.fontScale
367+ if (info.apiLevel != -1) tags["api_level"] = info.apiLevel
368+ if (info.widthDp > 0) tags["width_dp"] = info.widthDp
369+ if (info.heightDp > 0) tags["height_dp"] = info.heightDp
370+ if (info.showSystemUi) tags["show_system_ui"] = true
371+ if (info.showBackground) tags["show_background"] = true
372+
373+ val context = linkedMapOf<String, Any>(
362374 "image_file_name" to screenshotId,
363375 "class_name" to preview.declaringClass,
364376 "method_name" to preview.methodName,
365377 )
378+
379+ val metadata = linkedMapOf<String, Any>(
380+ "display_name" to screenshotId.removePrefix(preview.declaringClass + "."),
381+ )
366382 if (info.group.isNotBlank()) metadata["group"] = info.group
367- if (info.name.isNotBlank()) metadata["preview_name"] = info.name
368- if (info.locale.isNotBlank()) metadata["locale"] = info.locale
369- if (info.device.isNotBlank()) metadata["device"] = info.device
370- metadata["night_mode"] = (info.uiMode and UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES)
371- if (info.fontScale != 1f) metadata["font_scale"] = info.fontScale
372- if (info.apiLevel != -1) metadata["api_level"] = info.apiLevel
373- if (info.widthDp > 0) metadata["width_dp"] = info.widthDp
374- if (info.heightDp > 0) metadata["height_dp"] = info.heightDp
375- if (info.showSystemUi) metadata["show_system_ui"] = true
376- if (info.showBackground) metadata["show_background"] = true
383+
384+ when (info.uiMode and UI_MODE_NIGHT_MASK) {
385+ UI_MODE_NIGHT_YES -> metadata["color_mode"] = "dark"
386+ UI_MODE_NIGHT_NO -> metadata["color_mode"] = "light"
387+ }
377388
378389 val diffThreshold: Float? = runCatching {
379390 val declaring = Class.forName(preview.declaringClass)
@@ -386,15 +397,33 @@ class $CLASS_NAME(
386397 }.getOrNull()
387398 if (diffThreshold != null && diffThreshold != 0f) metadata["diff_threshold"] = diffThreshold
388399
389- val json = metadata.entries.joinToString(",\n ", prefix = "{\n ", postfix = "\n}") { (k, v) ->
390- if (v is String) "\"" + k + "\": \"" + escapeJson(v) + "\""
391- else "\"" + k + "\": " + v
392- }
400+ if (tags.isNotEmpty()) metadata["tags"] = tags
401+ metadata["context"] = context
402+
403+ val json = renderJson(metadata, 0)
393404 val sidecarName = "Paparazzi_Preview_Test_" +
394405 screenshotId.lowercase(Locale.US).replace("\\s".toRegex(), "_")
395406 File(imagesDir, "${' $' } {sidecarName}.json").writeText(json)
396407 }
397408
409+ private fun renderJson(value: Any, indentLevel: Int): String {
410+ val indent = " ".repeat(indentLevel)
411+ val childIndent = " ".repeat(indentLevel + 1)
412+ return when (value) {
413+ is String -> "\"" + escapeJson(value) + "\""
414+ is Boolean, is Number -> value.toString()
415+ is Map<*, *> -> when (value.isEmpty()) {
416+ true -> "{}"
417+ false -> value.entries.joinToString(
418+ separator = ",\n${' $' } childIndent",
419+ prefix = "{\n${' $' } childIndent",
420+ postfix = "\n${' $' } indent}",
421+ ) { (k, v) -> "\"${' $' } k\": " + renderJson(v!!, indentLevel + 1) }
422+ }
423+ else -> "\"" + escapeJson(value.toString()) + "\""
424+ }
425+ }
426+
398427 private fun escapeJson(s: String): String =
399428 s.replace("\\", "\\\\").replace("\"", "\\\"")
400429}
0 commit comments