1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
package reports
import (
"os"
"os/exec"
"path/filepath"
"punchcard/templates"
"testing"
"time"
)
// Helper function for tests
func mustParseDate(dateStr string) time.Time {
t, err := time.Parse("2006-01-02", dateStr)
if err != nil {
panic(err)
}
return t
}
func TestTypstTemplateCompilation(t *testing.T) {
// Check if Typst is installed
if err := checkTypstInstalled(); err != nil {
t.Skip("Typst is not installed, skipping template compilation test")
}
// Create temporary directory
tempDir, err := os.MkdirTemp("", "punchcard-test")
if err != nil {
t.Fatalf("Failed to create temp directory: %v", err)
}
defer os.RemoveAll(tempDir)
// Copy test data to temp directory
testDataPath := filepath.Join("testdata", "invoice_test_data.json")
testData, err := os.ReadFile(testDataPath)
if err != nil {
t.Fatalf("Failed to read test data: %v", err)
}
dataFile := filepath.Join(tempDir, "data.json")
if err := os.WriteFile(dataFile, testData, 0644); err != nil {
t.Fatalf("Failed to write test data file: %v", err)
}
// Write Typst template to temp directory
typstFile := filepath.Join(tempDir, "invoice.typ")
if err := os.WriteFile(typstFile, []byte(templates.InvoiceTemplate), 0644); err != nil {
t.Fatalf("Failed to write Typst template: %v", err)
}
// Compile with Typst
outputPDF := filepath.Join(tempDir, "test-invoice.pdf")
cmd := exec.Command("typst", "compile", typstFile, outputPDF)
cmd.Dir = tempDir
if output, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("Typst compilation failed: %v\nOutput: %s", err, string(output))
}
// Verify PDF was created
if _, err := os.Stat(outputPDF); os.IsNotExist(err) {
t.Fatalf("PDF file was not created")
}
t.Logf("Successfully compiled Typst template to PDF")
}
func TestGenerateInvoicePDF(t *testing.T) {
// Check if Typst is installed
if err := checkTypstInstalled(); err != nil {
t.Skip("Typst is not installed, skipping PDF generation test")
}
// Create test invoice data
invoiceData := &InvoiceData{
ClientName: "Test Client Co.",
ProjectName: "Test Project",
DateRange: DateRange{
Start: mustParseDate("2025-07-01"),
End: mustParseDate("2025-07-31"),
},
LineItems: []LineItem{
{
Description: "Software development",
Hours: 8.5,
Rate: 150.0,
Amount: 1275.0,
},
{
Description: "Code review",
Hours: 1.5,
Rate: 150.0,
Amount: 225.0,
},
},
TotalHours: 10.0,
TotalAmount: 1500.0,
GeneratedDate: mustParseDate("2025-08-04"),
}
// Create temporary output file
tempDir, err := os.MkdirTemp("", "punchcard-pdf-test")
if err != nil {
t.Fatalf("Failed to create temp directory: %v", err)
}
defer os.RemoveAll(tempDir)
outputPath := filepath.Join(tempDir, "test-invoice.pdf")
// Generate PDF
if err := GenerateInvoicePDF(invoiceData, outputPath); err != nil {
t.Fatalf("Failed to generate invoice PDF: %v", err)
}
// Verify PDF was created
if _, err := os.Stat(outputPath); os.IsNotExist(err) {
t.Fatalf("PDF file was not created at %s", outputPath)
}
t.Logf("Successfully generated invoice PDF at %s", outputPath)
}
|