feat(ui): content-measured History columns, shared caption widths, settings_view split
Stage 5: generalize logColumnWidth into textColumnWidth so History's Trigger/Job/State/Detail/Log columns size from measured text instead of pixel constants that clipped at larger text sizes (F6, F14). Stage 6: captionColumnWidth replaces detailCaptionWidth and settingsLabelWidth with one theme-derived helper; jobs_view_details.go now builds its metadata rows and their width from a single metadataRows() list instead of two hand-kept ones (F10); the Settings button row drops its transparent-rectangle spacers for a CustomPaddedLayout (F8); the remaining eight fyne.TextTruncate call sites move to the non-deprecated Truncation field (N1). Stage 7: settings_view.go split into settings_view.go (field construction/save/load/validate), settings_view_layout.go (the two-column layout and settingsSection/settingsRow), and settings_view_helpers.go (fyneVersion, dialogs, path helpers), mirroring the jobs_view.go split. Along the way, Queue/Storage's inline VBox and Application/About's settingsSection collapse into one settingsSection(title, spacing, rows...) constructor, and chooseFile/chooseJSONFile merge into one function with a filter argument. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -218,6 +219,79 @@ func TestHistoryCellTemplateIsPlainText(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestTextColumnWidthClamps covers the three shapes textColumnWidth has to
|
||||
// handle: a sample narrower than min, one that lands between the bounds, and
|
||||
// one wide enough to hit the max cap.
|
||||
func TestTextColumnWidthClamps(t *testing.T) {
|
||||
testApp := test.NewApp()
|
||||
defer testApp.Quit()
|
||||
|
||||
min, max := float32(50), float32(120)
|
||||
if got := textColumnWidth([]string{"x"}, min, max); got != min {
|
||||
t.Errorf("below-min sample: got %v, want the floor %v", got, min)
|
||||
}
|
||||
inRange := textWidth("mid-sized value") + cellPadding()
|
||||
if inRange <= min || inRange >= max {
|
||||
t.Skip("fixture sample no longer lands strictly between the bounds under this theme")
|
||||
}
|
||||
if got := textColumnWidth([]string{"mid-sized value"}, min, max); got != inRange {
|
||||
t.Errorf("in-range sample: got %v, want %v", got, inRange)
|
||||
}
|
||||
if got := textColumnWidth([]string{strings.Repeat("0", 200)}, min, max); got != max {
|
||||
t.Errorf("above-max sample: got %v, want the cap %v", got, max)
|
||||
}
|
||||
if got := textColumnWidth(nil, min, max); got != min {
|
||||
t.Errorf("no samples: got %v, want the floor %v", got, min)
|
||||
}
|
||||
}
|
||||
|
||||
// TestHistoryColumnsFitTheirContent guards F6/F14: every column must be at
|
||||
// least as wide as its widest known or actually-present value, at the default
|
||||
// theme and at a scaled one, so nothing that used to be a pixel constant
|
||||
// clips again.
|
||||
func TestHistoryColumnsFitTheirContent(t *testing.T) {
|
||||
testApp := test.NewApp()
|
||||
defer testApp.Quit()
|
||||
|
||||
rows := []event{
|
||||
{
|
||||
Time: "2026-06-01 12:00:00",
|
||||
Trigger: "Schedule",
|
||||
JobName: "A moderately long job name for width testing",
|
||||
State: "Jobs loaded",
|
||||
Detail: "A somewhat longer detail message describing what happened",
|
||||
LogFile: `/logs/20260601-120000_SomeJobName.log`,
|
||||
},
|
||||
}
|
||||
|
||||
check := func(when string) {
|
||||
t.Helper()
|
||||
widths := historyColumnWidths(rows)
|
||||
samples := [][]string{
|
||||
{historyTimeSample},
|
||||
historyTriggerSamples,
|
||||
{rows[0].JobName},
|
||||
historyStateSamples,
|
||||
{rows[0].Detail},
|
||||
{logFileName(rows[0].LogFile)},
|
||||
}
|
||||
min, max := textColumnMinWidth(), textColumnMaxWidth()
|
||||
for col, colSamples := range samples {
|
||||
want := textColumnWidth(colSamples, min, max)
|
||||
if col == 0 {
|
||||
want = textWidth(historyTimeSample) + cellPadding()
|
||||
}
|
||||
if widths[col] < want {
|
||||
t.Errorf("%s: column %d width = %v, want at least %v", when, col, widths[col], want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check("default theme")
|
||||
testApp.Settings().SetTheme(test.NewTheme())
|
||||
check("scaled theme")
|
||||
}
|
||||
|
||||
func TestNewEventUsesConsistentTimestampShape(t *testing.T) {
|
||||
ev := newEvent(1, "Job", "OK", "detail")
|
||||
if _, err := time.Parse("2006-01-02 15:04:05", ev.Time); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user