Add fonts, autotable, autotable examples
This commit is contained in:
91
go/webui/pdf_border_test.go
Normal file
91
go/webui/pdf_border_test.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package webui
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// pdfHorizontalRules extracts every horizontal line the PDF draws, as (y, width).
|
||||
// The content stream draws a line as: "<w> w <x1> <y> m <x2> <y> l S".
|
||||
func pdfHorizontalRules(pdf []byte) map[string]int {
|
||||
re := regexp.MustCompile(`([\d.]+) w\s*\n?[^\n]*?([\d.]+) ([\d.]+) m\s*\n?[^\n]*?([\d.]+) ([\d.]+) l`)
|
||||
out := map[string]int{}
|
||||
for _, m := range re.FindAllStringSubmatch(string(pdf), -1) {
|
||||
y1, y2 := m[3], m[5]
|
||||
if y1 != y2 {
|
||||
continue // not horizontal
|
||||
}
|
||||
out[y1]++
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// The bug: the row loop drew a rule under EVERY row including the last, and then the
|
||||
// summary block drew its divider at exactly the same y. Two rules at one y read as a
|
||||
// double border between the table and its summaries.
|
||||
func TestPDFDrawsOneRuleBetweenTableAndSummaries(t *testing.T) {
|
||||
s := newCalcTable()
|
||||
s.AddSummaryRow(UserSummaryRow{ID: "t", Label: "Total", Fn: CALC_FN_SUM,
|
||||
Operands: []string{"Revenue"}, DataType: CALC_TYPE_NUMBER, Precision: CalcPrecision(0)})
|
||||
s.Render()
|
||||
|
||||
rules := pdfHorizontalRules(s.ExportPDFBytes(AutoTablePDFHeader{Title: "R"}))
|
||||
if len(rules) == 0 {
|
||||
t.Fatal("no horizontal rules found — the extractor is wrong, not the PDF")
|
||||
}
|
||||
for y, n := range rules {
|
||||
if n > 1 {
|
||||
t.Errorf("%d rules stacked at y=%s — that is the double border", n, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Without summaries the table still gets its closing rule; removing the last row's
|
||||
// rule must not leave the table open at the bottom.
|
||||
func TestPDFClosesTheTableWithoutSummaries(t *testing.T) {
|
||||
s := newCalcTable()
|
||||
s.Render()
|
||||
pdf := s.ExportPDFBytes(AutoTablePDFHeader{Title: "R"})
|
||||
|
||||
rules := pdfHorizontalRules(pdf)
|
||||
if len(rules) < 2 {
|
||||
t.Errorf("expected a header rule and a closing rule, got %d distinct rules", len(rules))
|
||||
}
|
||||
for y, n := range rules {
|
||||
if n > 1 {
|
||||
t.Errorf("%d rules stacked at y=%s", n, y)
|
||||
}
|
||||
}
|
||||
|
||||
// And the lowest rule sits below the last row of text, i.e. the table is closed.
|
||||
lowest := 1e9
|
||||
for y := range rules {
|
||||
if f, err := strconv.ParseFloat(y, 64); err == nil && f < lowest {
|
||||
lowest = f
|
||||
}
|
||||
}
|
||||
if lowest > 700 || !strings.Contains(string(pdf), "%%EOF") {
|
||||
t.Errorf("closing rule at y=%v looks wrong", lowest)
|
||||
}
|
||||
}
|
||||
|
||||
// The extractor must actually see stacked rules, or the two tests above are vacuous.
|
||||
func TestPDFRuleExtractorCatchesADoubledRule(t *testing.T) {
|
||||
pdf := NewPDF(PDFOptions{})
|
||||
pdf.Line(50, 300, 500, 300, 0.5, PDFColor{})
|
||||
pdf.Line(50, 300, 500, 300, 1, PDFColor{}) // deliberately stacked
|
||||
pdf.Line(50, 200, 500, 200, 0.5, PDFColor{})
|
||||
|
||||
rules := pdfHorizontalRules(pdf.Bytes())
|
||||
doubled := 0
|
||||
for _, n := range rules {
|
||||
if n > 1 {
|
||||
doubled++
|
||||
}
|
||||
}
|
||||
if doubled != 1 {
|
||||
t.Fatalf("extractor found %d stacked positions, want exactly 1 — it cannot see the bug it is meant to catch (%v)", doubled, rules)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user