mirror of
https://github.com/duhanbalci/dreport.git
synced 2026-07-01 18:39:16 +00:00
visual testing
This commit is contained in:
33
layout-engine/tests/fixtures/chart_test_data.json
vendored
Normal file
33
layout-engine/tests/fixtures/chart_test_data.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"satis": [
|
||||
{ "ay": "Ocak", "gelir": 15000, "kanal": "Online" },
|
||||
{ "ay": "Ocak", "gelir": 8000, "kanal": "Magaza" },
|
||||
{ "ay": "Ocak", "gelir": 3000, "kanal": "Toptan" },
|
||||
{ "ay": "Subat", "gelir": 18000, "kanal": "Online" },
|
||||
{ "ay": "Subat", "gelir": 9500, "kanal": "Magaza" },
|
||||
{ "ay": "Subat", "gelir": 4200, "kanal": "Toptan" },
|
||||
{ "ay": "Mart", "gelir": 22000, "kanal": "Online" },
|
||||
{ "ay": "Mart", "gelir": 11000, "kanal": "Magaza" },
|
||||
{ "ay": "Mart", "gelir": 5100, "kanal": "Toptan" },
|
||||
{ "ay": "Nisan", "gelir": 19500, "kanal": "Online" },
|
||||
{ "ay": "Nisan", "gelir": 10200, "kanal": "Magaza" },
|
||||
{ "ay": "Nisan", "gelir": 4800, "kanal": "Toptan" }
|
||||
],
|
||||
"trend": [
|
||||
{ "hafta": "H1", "ziyaretci": 1200, "kaynak": "Organik" },
|
||||
{ "hafta": "H1", "ziyaretci": 800, "kaynak": "Reklam" },
|
||||
{ "hafta": "H2", "ziyaretci": 1500, "kaynak": "Organik" },
|
||||
{ "hafta": "H2", "ziyaretci": 950, "kaynak": "Reklam" },
|
||||
{ "hafta": "H3", "ziyaretci": 1350, "kaynak": "Organik" },
|
||||
{ "hafta": "H3", "ziyaretci": 1100, "kaynak": "Reklam" },
|
||||
{ "hafta": "H4", "ziyaretci": 1800, "kaynak": "Organik" },
|
||||
{ "hafta": "H4", "ziyaretci": 1250, "kaynak": "Reklam" }
|
||||
],
|
||||
"dagilim": [
|
||||
{ "kategori": "Elektronik", "oran": 35 },
|
||||
{ "kategori": "Giyim", "oran": 25 },
|
||||
{ "kategori": "Gida", "oran": 20 },
|
||||
{ "kategori": "Kozmetik", "oran": 12 },
|
||||
{ "kategori": "Diger", "oran": 8 }
|
||||
]
|
||||
}
|
||||
131
layout-engine/tests/fixtures/chart_test_template.json
vendored
Normal file
131
layout-engine/tests/fixtures/chart_test_template.json
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"id": "chart_test",
|
||||
"name": "Chart Visual Test",
|
||||
"page": { "width": 210, "height": 297 },
|
||||
"fonts": ["Noto Sans"],
|
||||
"root": {
|
||||
"id": "root",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"direction": "column",
|
||||
"gap": 8,
|
||||
"padding": { "top": 15, "right": 15, "bottom": 15, "left": 15 },
|
||||
"align": "stretch",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "bar_chart",
|
||||
"type": "chart",
|
||||
"position": { "type": "flow" },
|
||||
"size": {
|
||||
"width": { "type": "fr", "value": 1 },
|
||||
"height": { "type": "fixed", "value": 80 }
|
||||
},
|
||||
"chartType": "bar",
|
||||
"dataSource": { "path": "satis" },
|
||||
"categoryField": "ay",
|
||||
"valueField": "gelir",
|
||||
"groupField": "kanal",
|
||||
"groupMode": "grouped",
|
||||
"title": {
|
||||
"text": "Aylik Satis Geliri",
|
||||
"fontSize": 4.0,
|
||||
"color": "#1a1a1a"
|
||||
},
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "bottom",
|
||||
"fontSize": 2.8
|
||||
},
|
||||
"labels": {
|
||||
"show": true,
|
||||
"fontSize": 2.2,
|
||||
"color": "#333333"
|
||||
},
|
||||
"axis": {
|
||||
"xLabel": "Aylar",
|
||||
"yLabel": "Gelir (TL)",
|
||||
"showGrid": true,
|
||||
"gridColor": "#E5E7EB"
|
||||
},
|
||||
"style": {
|
||||
"colors": ["#4F46E5", "#10B981", "#F59E0B"],
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"barGap": 0.2
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "line_chart",
|
||||
"type": "chart",
|
||||
"position": { "type": "flow" },
|
||||
"size": {
|
||||
"width": { "type": "fr", "value": 1 },
|
||||
"height": { "type": "fixed", "value": 80 }
|
||||
},
|
||||
"chartType": "line",
|
||||
"dataSource": { "path": "trend" },
|
||||
"categoryField": "hafta",
|
||||
"valueField": "ziyaretci",
|
||||
"groupField": "kaynak",
|
||||
"title": {
|
||||
"text": "Haftalik Ziyaretci Trendi",
|
||||
"fontSize": 4.0,
|
||||
"color": "#1a1a1a"
|
||||
},
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "bottom",
|
||||
"fontSize": 2.8
|
||||
},
|
||||
"labels": {
|
||||
"show": false
|
||||
},
|
||||
"axis": {
|
||||
"showGrid": true,
|
||||
"gridColor": "#E5E7EB"
|
||||
},
|
||||
"style": {
|
||||
"colors": ["#EF4444", "#8B5CF6"],
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"lineWidth": 0.5,
|
||||
"showPoints": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "pie_chart",
|
||||
"type": "chart",
|
||||
"position": { "type": "flow" },
|
||||
"size": {
|
||||
"width": { "type": "fr", "value": 1 },
|
||||
"height": { "type": "fixed", "value": 80 }
|
||||
},
|
||||
"chartType": "pie",
|
||||
"dataSource": { "path": "dagilim" },
|
||||
"categoryField": "kategori",
|
||||
"valueField": "oran",
|
||||
"title": {
|
||||
"text": "Kategori Dagilimi",
|
||||
"fontSize": 4.0,
|
||||
"color": "#1a1a1a"
|
||||
},
|
||||
"legend": {
|
||||
"show": true,
|
||||
"position": "right",
|
||||
"fontSize": 2.8
|
||||
},
|
||||
"labels": {
|
||||
"show": true,
|
||||
"fontSize": 2.5,
|
||||
"color": "#FFFFFF"
|
||||
},
|
||||
"style": {
|
||||
"colors": ["#4F46E5", "#10B981", "#F59E0B", "#EF4444", "#8B5CF6"],
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"innerRadius": 0.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
42
layout-engine/tests/fixtures/comprehensive_test_data.json
vendored
Normal file
42
layout-engine/tests/fixtures/comprehensive_test_data.json
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"company": {
|
||||
"name": "Teknova Yazilim A.S.",
|
||||
"city": "Istanbul",
|
||||
"revenue": 148200
|
||||
},
|
||||
"order": {
|
||||
"code": "ORD-2026-0042"
|
||||
},
|
||||
"meta": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"products": [
|
||||
{ "no": 1, "name": "Web Application Development", "qty": 1, "price": 45000, "total": 45000 },
|
||||
{ "no": 2, "name": "Mobile App Development", "qty": 1, "price": 35000, "total": 35000 },
|
||||
{ "no": 3, "name": "UI/UX Design Service", "qty": 40, "price": 750, "total": 30000 },
|
||||
{ "no": 4, "name": "Server Maintenance (Annual)", "qty": 1, "price": 12000, "total": 12000 },
|
||||
{ "no": 5, "name": "SSL Certificate", "qty": 3, "price": 500, "total": 1500 },
|
||||
{ "no": 6, "name": "Cloud Hosting Setup", "qty": 1, "price": 8500, "total": 8500 },
|
||||
{ "no": 7, "name": "Database Optimization", "qty": 2, "price": 6000, "total": 12000 }
|
||||
],
|
||||
"distribution": [
|
||||
{ "category": "Development", "value": 80000 },
|
||||
{ "category": "Design", "value": 30000 },
|
||||
{ "category": "Infrastructure", "value": 22000 },
|
||||
{ "category": "Support", "value": 12000 }
|
||||
],
|
||||
"trend": [
|
||||
{ "month": "Jan", "series": "Revenue", "value": 18000 },
|
||||
{ "month": "Feb", "series": "Revenue", "value": 22000 },
|
||||
{ "month": "Mar", "series": "Revenue", "value": 19500 },
|
||||
{ "month": "Apr", "series": "Revenue", "value": 28000 },
|
||||
{ "month": "May", "series": "Revenue", "value": 32000 },
|
||||
{ "month": "Jun", "series": "Revenue", "value": 35000 },
|
||||
{ "month": "Jan", "series": "Costs", "value": 12000 },
|
||||
{ "month": "Feb", "series": "Costs", "value": 14000 },
|
||||
{ "month": "Mar", "series": "Costs", "value": 11000 },
|
||||
{ "month": "Apr", "series": "Costs", "value": 16000 },
|
||||
{ "month": "May", "series": "Costs", "value": 18000 },
|
||||
{ "month": "Jun", "series": "Costs", "value": 20000 }
|
||||
]
|
||||
}
|
||||
466
layout-engine/tests/fixtures/comprehensive_test_template.json
vendored
Normal file
466
layout-engine/tests/fixtures/comprehensive_test_template.json
vendored
Normal file
@@ -0,0 +1,466 @@
|
||||
{
|
||||
"id": "comprehensive_test",
|
||||
"name": "Comprehensive Element Test",
|
||||
"page": { "width": 210, "height": 297 },
|
||||
"fonts": ["Noto Sans", "Noto Sans Mono"],
|
||||
"root": {
|
||||
"id": "root",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"direction": "column",
|
||||
"gap": 4,
|
||||
"padding": { "top": 12, "right": 12, "bottom": 12, "left": 12 },
|
||||
"align": "stretch",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
|
||||
{
|
||||
"id": "title",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 16, "fontWeight": "bold", "color": "#1a1a1a", "align": "center" },
|
||||
"content": "COMPREHENSIVE ELEMENT TEST"
|
||||
},
|
||||
|
||||
{
|
||||
"id": "subtitle",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 9, "color": "#888888", "align": "center" },
|
||||
"content": "All element types in a single document"
|
||||
},
|
||||
|
||||
{
|
||||
"id": "line_top",
|
||||
"type": "line",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"style": { "strokeColor": "#1e293b", "strokeWidth": 1 }
|
||||
},
|
||||
|
||||
{
|
||||
"id": "section_text",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "column",
|
||||
"gap": 2,
|
||||
"padding": { "top": 2, "right": 4, "bottom": 2, "left": 4 },
|
||||
"align": "stretch",
|
||||
"justify": "start",
|
||||
"style": { "backgroundColor": "#f0f4ff", "borderColor": "#c7d2fe", "borderWidth": 0.5, "borderRadius": 2 },
|
||||
"children": [
|
||||
{
|
||||
"id": "sec1_label",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 8, "fontWeight": "bold", "color": "#4338ca" },
|
||||
"content": "TEXT ELEMENTS"
|
||||
},
|
||||
{
|
||||
"id": "row_texts",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "row",
|
||||
"gap": 4,
|
||||
"padding": { "top": 0, "right": 0, "bottom": 0, "left": 0 },
|
||||
"align": "start",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "bound_text",
|
||||
"type": "text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 10, "color": "#333333" },
|
||||
"content": "Company: ",
|
||||
"binding": { "path": "company.name" }
|
||||
},
|
||||
{
|
||||
"id": "bound_text2",
|
||||
"type": "text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 10, "color": "#333333" },
|
||||
"content": "City: ",
|
||||
"binding": { "path": "company.city" }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "rich_text_el",
|
||||
"type": "rich_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 9, "color": "#333333" },
|
||||
"content": [
|
||||
{ "text": "Rich text: ", "style": { "fontSize": 9, "fontWeight": "bold", "color": "#1e293b" } },
|
||||
{ "text": "normal ", "style": { "fontSize": 9, "color": "#555555" } },
|
||||
{ "text": "bold ", "style": { "fontSize": 9, "fontWeight": "bold", "color": "#dc2626" } },
|
||||
{ "text": "large ", "style": { "fontSize": 12, "color": "#059669" } },
|
||||
{ "text": "mono", "style": { "fontSize": 9, "fontFamily": "Noto Sans Mono", "color": "#7c3aed" } }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "calc_text",
|
||||
"type": "calculated_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 9, "color": "#333333" },
|
||||
"expression": "company.revenue * 0.20",
|
||||
"format": "currency"
|
||||
},
|
||||
{
|
||||
"id": "row_date_page",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "row",
|
||||
"gap": 8,
|
||||
"padding": { "top": 0, "right": 0, "bottom": 0, "left": 0 },
|
||||
"align": "center",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "date_el",
|
||||
"type": "current_date",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 9, "color": "#666666" },
|
||||
"format": "DD.MM.YYYY"
|
||||
},
|
||||
{
|
||||
"id": "page_num",
|
||||
"type": "page_number",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 9, "color": "#666666" },
|
||||
"format": "Page {current}/{total}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "line_thin",
|
||||
"type": "line",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"style": { "strokeColor": "#e2e8f0", "strokeWidth": 0.3 }
|
||||
},
|
||||
|
||||
{
|
||||
"id": "section_shapes",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "column",
|
||||
"gap": 2,
|
||||
"padding": { "top": 2, "right": 4, "bottom": 2, "left": 4 },
|
||||
"align": "stretch",
|
||||
"justify": "start",
|
||||
"style": { "backgroundColor": "#fef3c7", "borderColor": "#fbbf24", "borderWidth": 0.5, "borderRadius": 2 },
|
||||
"children": [
|
||||
{
|
||||
"id": "sec2_label",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 8, "fontWeight": "bold", "color": "#92400e" },
|
||||
"content": "SHAPES, CHECKBOXES & BARCODES"
|
||||
},
|
||||
{
|
||||
"id": "row_shapes",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "row",
|
||||
"gap": 4,
|
||||
"padding": { "top": 0, "right": 0, "bottom": 0, "left": 0 },
|
||||
"align": "center",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "shape_rect",
|
||||
"type": "shape",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 15 }, "height": { "type": "fixed", "value": 10 } },
|
||||
"shapeType": "rectangle",
|
||||
"style": { "backgroundColor": "#3b82f6", "borderColor": "#1d4ed8", "borderWidth": 0.5 }
|
||||
},
|
||||
{
|
||||
"id": "shape_ellipse",
|
||||
"type": "shape",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 15 }, "height": { "type": "fixed", "value": 10 } },
|
||||
"shapeType": "ellipse",
|
||||
"style": { "backgroundColor": "#ef4444", "borderColor": "#b91c1c", "borderWidth": 0.5 }
|
||||
},
|
||||
{
|
||||
"id": "shape_rounded",
|
||||
"type": "shape",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 15 }, "height": { "type": "fixed", "value": 10 } },
|
||||
"shapeType": "rounded_rectangle",
|
||||
"style": { "backgroundColor": "#10b981", "borderColor": "#047857", "borderWidth": 0.5, "borderRadius": 3 }
|
||||
},
|
||||
{
|
||||
"id": "cb_checked",
|
||||
"type": "checkbox",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 5 }, "height": { "type": "fixed", "value": 5 } },
|
||||
"checked": true,
|
||||
"style": { "size": 5, "checkColor": "#059669", "borderColor": "#333333", "borderWidth": 0.3 }
|
||||
},
|
||||
{
|
||||
"id": "cb_label1",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 8, "color": "#333333" },
|
||||
"content": "Checked"
|
||||
},
|
||||
{
|
||||
"id": "cb_unchecked",
|
||||
"type": "checkbox",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 5 }, "height": { "type": "fixed", "value": 5 } },
|
||||
"checked": false,
|
||||
"style": { "size": 5, "checkColor": "#000000", "borderColor": "#333333", "borderWidth": 0.3 }
|
||||
},
|
||||
{
|
||||
"id": "cb_label2",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 8, "color": "#333333" },
|
||||
"content": "Unchecked"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "row_barcodes",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "row",
|
||||
"gap": 6,
|
||||
"padding": { "top": 2, "right": 0, "bottom": 0, "left": 0 },
|
||||
"align": "start",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "barcode_qr",
|
||||
"type": "barcode",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 20 }, "height": { "type": "fixed", "value": 20 } },
|
||||
"format": "qr",
|
||||
"value": "https://dreport.dev",
|
||||
"style": {}
|
||||
},
|
||||
{
|
||||
"id": "barcode_128",
|
||||
"type": "barcode",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 40 }, "height": { "type": "fixed", "value": 15 } },
|
||||
"format": "code128",
|
||||
"binding": { "path": "order.code" },
|
||||
"style": { "includeText": true }
|
||||
},
|
||||
{
|
||||
"id": "barcode_ean",
|
||||
"type": "barcode",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 35 }, "height": { "type": "fixed", "value": 15 } },
|
||||
"format": "ean13",
|
||||
"value": "5901234123457",
|
||||
"style": { "includeText": true }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "section_table",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "column",
|
||||
"gap": 2,
|
||||
"padding": { "top": 2, "right": 0, "bottom": 0, "left": 0 },
|
||||
"align": "stretch",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "sec3_label",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 8, "fontWeight": "bold", "color": "#0f766e" },
|
||||
"content": "REPEATING TABLE"
|
||||
},
|
||||
{
|
||||
"id": "products_table",
|
||||
"type": "repeating_table",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"dataSource": { "path": "products" },
|
||||
"columns": [
|
||||
{ "id": "col_no", "field": "no", "title": "#", "width": { "type": "fixed", "value": 8 }, "align": "center" },
|
||||
{ "id": "col_name", "field": "name", "title": "Product", "width": { "type": "fr", "value": 1 }, "align": "left" },
|
||||
{ "id": "col_qty", "field": "qty", "title": "Qty", "width": { "type": "fixed", "value": 15 }, "align": "right" },
|
||||
{ "id": "col_price", "field": "price", "title": "Price", "width": { "type": "fixed", "value": 25 }, "align": "right", "format": "currency" },
|
||||
{ "id": "col_total", "field": "total", "title": "Total", "width": { "type": "fixed", "value": 25 }, "align": "right", "format": "currency" }
|
||||
],
|
||||
"style": {
|
||||
"fontSize": 8,
|
||||
"headerFontSize": 8,
|
||||
"headerBg": "#0f766e",
|
||||
"headerColor": "#ffffff",
|
||||
"zebraOdd": "#ffffff",
|
||||
"zebraEven": "#f0fdfa",
|
||||
"borderColor": "#99f6e4",
|
||||
"borderWidth": 0.3
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "section_charts",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "column",
|
||||
"gap": 2,
|
||||
"padding": { "top": 2, "right": 0, "bottom": 0, "left": 0 },
|
||||
"align": "stretch",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "sec4_label",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 8, "fontWeight": "bold", "color": "#9333ea" },
|
||||
"content": "CHARTS"
|
||||
},
|
||||
{
|
||||
"id": "charts_row",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "row",
|
||||
"gap": 4,
|
||||
"padding": { "top": 0, "right": 0, "bottom": 0, "left": 0 },
|
||||
"align": "start",
|
||||
"justify": "start",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "chart_bar",
|
||||
"type": "chart",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "fixed", "value": 45 } },
|
||||
"chartType": "bar",
|
||||
"dataSource": { "path": "products" },
|
||||
"categoryField": "name",
|
||||
"valueField": "total",
|
||||
"title": { "text": "Revenue by Product", "fontSize": 3, "color": "#1e293b" },
|
||||
"legend": { "show": false },
|
||||
"labels": { "show": true, "fontSize": 2, "color": "#333" },
|
||||
"axis": { "showGrid": true },
|
||||
"style": { "colors": ["#6366f1", "#22c55e", "#f59e0b", "#ef4444", "#8b5cf6"] }
|
||||
},
|
||||
{
|
||||
"id": "chart_pie",
|
||||
"type": "chart",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fixed", "value": 55 }, "height": { "type": "fixed", "value": 45 } },
|
||||
"chartType": "pie",
|
||||
"dataSource": { "path": "distribution" },
|
||||
"categoryField": "category",
|
||||
"valueField": "value",
|
||||
"title": { "text": "Distribution", "fontSize": 3, "color": "#1e293b" },
|
||||
"legend": { "show": true, "position": "bottom", "fontSize": 2 },
|
||||
"labels": { "show": true, "fontSize": 2, "color": "#333" },
|
||||
"style": { "colors": ["#3b82f6", "#ef4444", "#10b981", "#f59e0b"], "innerRadius": 0.4 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "chart_line",
|
||||
"type": "chart",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "fixed", "value": 40 } },
|
||||
"chartType": "line",
|
||||
"dataSource": { "path": "trend" },
|
||||
"categoryField": "month",
|
||||
"valueField": "value",
|
||||
"groupField": "series",
|
||||
"title": { "text": "Monthly Trend", "fontSize": 3, "color": "#1e293b" },
|
||||
"legend": { "show": true, "position": "top", "fontSize": 2 },
|
||||
"labels": { "show": false },
|
||||
"axis": { "showGrid": true },
|
||||
"style": { "colors": ["#6366f1", "#ef4444"], "lineWidth": 1.5, "showPoints": true }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "line_bottom",
|
||||
"type": "line",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"style": { "strokeColor": "#1e293b", "strokeWidth": 0.5 }
|
||||
},
|
||||
|
||||
{
|
||||
"id": "footer_row",
|
||||
"type": "container",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "fr", "value": 1 }, "height": { "type": "auto" } },
|
||||
"direction": "row",
|
||||
"gap": 0,
|
||||
"padding": { "top": 0, "right": 0, "bottom": 0, "left": 0 },
|
||||
"align": "center",
|
||||
"justify": "space-between",
|
||||
"style": {},
|
||||
"children": [
|
||||
{
|
||||
"id": "footer_left",
|
||||
"type": "static_text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 7, "color": "#94a3b8" },
|
||||
"content": "Generated by dreport visual test suite"
|
||||
},
|
||||
{
|
||||
"id": "footer_right",
|
||||
"type": "text",
|
||||
"position": { "type": "flow" },
|
||||
"size": { "width": { "type": "auto" }, "height": { "type": "auto" } },
|
||||
"style": { "fontSize": 7, "color": "#94a3b8", "align": "right" },
|
||||
"content": "Version: ",
|
||||
"binding": { "path": "meta.version" }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
layout-engine/tests/snapshots/chart_test_reference.png
Normal file
BIN
layout-engine/tests/snapshots/chart_test_reference.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
1
layout-engine/tests/snapshots/chart_test_svg.html
Normal file
1
layout-engine/tests/snapshots/chart_test_svg.html
Normal file
File diff suppressed because one or more lines are too long
@@ -13,7 +13,7 @@ mod visual {
|
||||
use std::process::Command;
|
||||
|
||||
use dreport_core::models::Template;
|
||||
use dreport_layout::{compute_layout, FontData};
|
||||
use dreport_layout::{compute_layout, FontData, ResolvedContent};
|
||||
use dreport_layout::pdf_render::render_pdf;
|
||||
|
||||
fn fixtures_dir() -> std::path::PathBuf {
|
||||
@@ -156,17 +156,15 @@ mod visual {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_visual_snapshot_basic() {
|
||||
let pdf_bytes =
|
||||
generate_test_pdf("visual_test_template.json", "visual_test_data.json");
|
||||
fn run_visual_test(template_file: &str, data_file: &str, test_name: &str) {
|
||||
let pdf_bytes = generate_test_pdf(template_file, data_file);
|
||||
assert!(!pdf_bytes.is_empty(), "PDF should not be empty");
|
||||
|
||||
let snap_dir = snapshots_dir();
|
||||
fs::create_dir_all(&snap_dir).unwrap();
|
||||
|
||||
let actual_png = snap_dir.join("visual_test_actual.png");
|
||||
let reference_png = snap_dir.join("visual_test_reference.png");
|
||||
let actual_png = snap_dir.join(format!("{}_actual.png", test_name));
|
||||
let reference_png = snap_dir.join(format!("{}_reference.png", test_name));
|
||||
|
||||
if !pdf_to_png(&pdf_bytes, &actual_png) {
|
||||
eprintln!("Skipping visual comparison - pdftoppm not available");
|
||||
@@ -188,7 +186,8 @@ mod visual {
|
||||
match compare_images(&actual_png, &reference_png, 0.01) {
|
||||
Ok(diff) => {
|
||||
println!(
|
||||
"Visual test passed: {:.4}% pixels differ",
|
||||
"Visual test [{}] passed: {:.4}% pixels differ",
|
||||
test_name,
|
||||
diff * 100.0
|
||||
);
|
||||
let _ = fs::remove_file(&actual_png);
|
||||
@@ -196,10 +195,99 @@ mod visual {
|
||||
Err(err) => {
|
||||
// Keep actual for debugging
|
||||
panic!(
|
||||
"Visual regression detected: {}. Actual saved at {:?}",
|
||||
err, actual_png
|
||||
"Visual regression [{}]: {}. Actual saved at {:?}",
|
||||
test_name, err, actual_png
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// SVG'yi standalone HTML'e sar — chart'ın HTML render'ını görmek icin
|
||||
fn generate_chart_svg_html(template_file: &str, data_file: &str, output_path: &Path) {
|
||||
let template_json = fs::read_to_string(fixtures_dir().join(template_file)).unwrap();
|
||||
let data_json = fs::read_to_string(fixtures_dir().join(data_file)).unwrap();
|
||||
|
||||
let template: Template = serde_json::from_str(&template_json).unwrap();
|
||||
let data: serde_json::Value = serde_json::from_str(&data_json).unwrap();
|
||||
let fonts = load_test_fonts();
|
||||
|
||||
let layout = compute_layout(&template, &data, &fonts);
|
||||
|
||||
let mut html = String::from("<!DOCTYPE html><html><head><style>body{margin:20px;font-family:sans-serif;background:#f5f5f5}.chart-box{margin:10px 0;background:white;box-shadow:0 1px 3px rgba(0,0,0,.1)}</style></head><body><h2>Chart SVG Preview (HTML render)</h2>");
|
||||
|
||||
for page in &layout.pages {
|
||||
for el in &page.elements {
|
||||
if let Some(ResolvedContent::Chart { svg, .. }) = &el.content {
|
||||
html.push_str(&format!(
|
||||
"<div class='chart-box' style='width:{}mm;height:{}mm'>{}</div>",
|
||||
el.width_mm, el.height_mm, svg
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html.push_str("</body></html>");
|
||||
fs::write(output_path, html).unwrap();
|
||||
}
|
||||
|
||||
/// Cross-renderer reference PNG output directory
|
||||
fn cross_renderer_dir() -> std::path::PathBuf {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("frontend/tests/visual/cross-renderer-refs")
|
||||
}
|
||||
|
||||
/// Generates PDF→PNG references for cross-renderer comparison with HTML render.
|
||||
/// Run explicitly: cargo test -p dreport-layout --test visual_test -- generate_cross_renderer --ignored
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn generate_cross_renderer_refs() {
|
||||
let fixtures = [
|
||||
("visual_test_template.json", "visual_test_data.json", "visual_test"),
|
||||
("chart_test_template.json", "chart_test_data.json", "chart_test"),
|
||||
("comprehensive_test_template.json", "comprehensive_test_data.json", "comprehensive_test"),
|
||||
];
|
||||
|
||||
let out_dir = cross_renderer_dir();
|
||||
fs::create_dir_all(&out_dir).unwrap();
|
||||
|
||||
for (template_file, data_file, name) in &fixtures {
|
||||
let pdf_bytes = generate_test_pdf(template_file, data_file);
|
||||
assert!(!pdf_bytes.is_empty(), "PDF should not be empty for {}", name);
|
||||
|
||||
let png_path = out_dir.join(format!("{}.png", name));
|
||||
if !pdf_to_png(&pdf_bytes, &png_path) {
|
||||
panic!("pdftoppm failed for {} — install poppler-utils", name);
|
||||
}
|
||||
println!("Cross-renderer reference: {:?}", png_path);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_visual_snapshot_basic() {
|
||||
run_visual_test("visual_test_template.json", "visual_test_data.json", "visual_test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_visual_snapshot_charts() {
|
||||
let pdf_bytes = generate_test_pdf("chart_test_template.json", "chart_test_data.json");
|
||||
assert!(!pdf_bytes.is_empty(), "Chart PDF should not be empty");
|
||||
|
||||
let snap_dir = snapshots_dir();
|
||||
fs::create_dir_all(&snap_dir).unwrap();
|
||||
|
||||
// PDF ciktisini kaydet (inceleme icin)
|
||||
let pdf_path = snap_dir.join("chart_test.pdf");
|
||||
fs::write(&pdf_path, &pdf_bytes).unwrap();
|
||||
println!("Chart PDF saved to {:?}", pdf_path);
|
||||
|
||||
// SVG HTML ciktisini kaydet (karsilastirma icin)
|
||||
let html_path = snap_dir.join("chart_test_svg.html");
|
||||
generate_chart_svg_html("chart_test_template.json", "chart_test_data.json", &html_path);
|
||||
println!("Chart SVG HTML saved to {:?}", html_path);
|
||||
|
||||
// Visual regression test
|
||||
run_visual_test("chart_test_template.json", "chart_test_data.json", "chart_test");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user