export: revision UX de estilos, 2 estilos nuevos y copia como texto
- Header elegante: logo fijado a la izquierda y titulo centrado de verdad (ZStack), fecha a la derecha - School transpuesto: dias como columnas y comidas como filas — antes con 1-2 comidas quedaba media pagina A4 apaisada en blanco - Default: las celdas del grid se expanden para llenar la pagina (mismo sintoma de hueco que el school) - Estilo nuevo "Story" (9:16, 2160x3840) para stories de IG/WhatsApp y "Minimal (imprimir)" en A4 con lineas finas sin fondos (ahorro tinta) - Picker del preview pasa de segmentado a chips desplazables (5 estilos) - WeekPlanTextExporter + boton "Copiar como texto (WhatsApp)" en el preview: menu semanal con *negritas* y emojis listo para pegar en WhatsApp/Telegram (evento analytics format=text) - Harness de render en tests: genera PNG de los 5 estilos con datos de ejemplo en /tmp/mealmood-export-previews para revisar el diseno - Nombres de estilos en espanol corregidos (estaban en ingles) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
This commit is contained in:
@@ -1,6 +1,77 @@
|
||||
import XCTest
|
||||
import SwiftUI
|
||||
import SwiftData
|
||||
@testable import MealMood
|
||||
|
||||
/// Not a real assertion suite: renders every export style with sample data to
|
||||
/// /tmp/mealmood-export-previews/ so design changes can be reviewed as images.
|
||||
final class ExportStyleRenderTests: XCTestCase {
|
||||
|
||||
@MainActor
|
||||
func testRenderAllExportStyles() throws {
|
||||
let config = ModelConfiguration(isStoredInMemoryOnly: true)
|
||||
let container = try ModelContainer(
|
||||
for: AppSettings.self, Dish.self, Tag.self, WeekPlan.self, MealSlot.self,
|
||||
configurations: config
|
||||
)
|
||||
let context = container.mainContext
|
||||
|
||||
let settings = AppSettings()
|
||||
settings.activeMealTypes = [.lunch, .dinner]
|
||||
settings.includeWeekends = true
|
||||
settings.language = "es"
|
||||
context.insert(settings)
|
||||
|
||||
let names = [
|
||||
"Tortilla de patatas", "Salmón al horno", "Ensalada César",
|
||||
"Lentejas con chorizo", "Pizza casera", "Pollo asado con patatas",
|
||||
"Crema de calabaza", "Espaguetis boloñesa", "Merluza en salsa verde",
|
||||
"Arroz tres delicias", "Fajitas de pollo", "Gazpacho", "Croquetas caseras", "Sopa de fideos"
|
||||
]
|
||||
let dishes = names.map { Dish(name: $0) }
|
||||
dishes.forEach { context.insert($0) }
|
||||
|
||||
let monday = Calendar(identifier: .gregorian).date(from: DateComponents(year: 2026, month: 8, day: 31))!
|
||||
let plan = WeekPlan(weekStartDate: monday)
|
||||
context.insert(plan)
|
||||
var dishIndex = 0
|
||||
for day in 0...6 {
|
||||
for meal in [MealType.lunch, .dinner] {
|
||||
let slot = MealSlot(dayOfWeek: day, mealType: meal.rawValue)
|
||||
if day == 5 && meal == .dinner {
|
||||
slot.isEatingOut = true
|
||||
} else {
|
||||
slot.dishId = dishes[dishIndex % dishes.count].id
|
||||
if day == 2 && meal == .dinner {
|
||||
slot.secondaryDishId = dishes[(dishIndex + 5) % dishes.count].id
|
||||
}
|
||||
dishIndex += 1
|
||||
}
|
||||
slot.weekPlan = plan
|
||||
plan.slotList.append(slot)
|
||||
context.insert(slot)
|
||||
}
|
||||
}
|
||||
try context.save()
|
||||
|
||||
let outputDir = URL(fileURLWithPath: "/tmp/mealmood-export-previews")
|
||||
try? FileManager.default.createDirectory(at: outputDir, withIntermediateDirectories: true)
|
||||
|
||||
for style in WeekExportStyle.allCases {
|
||||
let renderer = ImageRenderer(content: WeekPlanShareView(
|
||||
plan: plan, settings: settings, dishes: dishes, tags: [],
|
||||
exportStyleOverride: style
|
||||
))
|
||||
let size = WeekPlanShareView.canvasSize(for: style)
|
||||
renderer.proposedSize = ProposedViewSize(width: size.width, height: size.height)
|
||||
renderer.scale = 1
|
||||
let image = try XCTUnwrap(renderer.uiImage, "render failed for \(style.rawValue)")
|
||||
let data = try XCTUnwrap(image.pngData())
|
||||
try data.write(to: outputDir.appendingPathComponent("export-\(style.rawValue).png"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class DateHelpersTests: XCTestCase {
|
||||
|
||||
func testStartOfWeekReturnsMonday() {
|
||||
|
||||
Reference in New Issue
Block a user