check / check (push) Successful in 3m21s
cmd/bsdaily/main.go now only passes Version to cli.Main and exits with the status it returns, as REPO_POLICIES.md requires of cmd/. The cobra command, the flag rules and the date parsing moved unchanged into internal/cli, so flags, help text, error messages, exit status and the first log line stay as they were. The fallback to dev for an empty version moved with them into cli.Main. parseTargetDates is exported as ParseTargetDates so that a table test outside the package can reach it; the test never touches the filesystem or runs the extraction. README describes the new layout and TODO.md records the step. Model: opus-5-5
110 lines
2.8 KiB
Go
110 lines
2.8 KiB
Go
package cli_test
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.eeqj.de/sneak/bsdaily/internal/cli"
|
|
)
|
|
|
|
func TestParseTargetDates(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const oneDay = "2026-05-14"
|
|
|
|
// want lists the expected days as YYYY-MM-DD.
|
|
tests := []struct {
|
|
name string
|
|
date string
|
|
from string
|
|
to string
|
|
want []string
|
|
}{
|
|
{name: "no flags"},
|
|
{name: "single date", date: "2026-06-27", want: []string{"2026-06-27"}},
|
|
{
|
|
name: "range across a month end", from: "2026-06-29", to: "2026-07-02",
|
|
want: []string{"2026-06-29", "2026-06-30", "2026-07-01", "2026-07-02"},
|
|
},
|
|
{name: "range of one day", from: oneDay, to: oneDay, want: []string{oneDay}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got, err := cli.ParseTargetDates(tt.date, tt.from, tt.to)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
days := make([]string, 0, len(got))
|
|
for _, day := range got {
|
|
days = append(days, day.Format("2006-01-02"))
|
|
}
|
|
|
|
if !slices.Equal(days, tt.want) {
|
|
t.Errorf("days = %v, want %v", days, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseTargetDatesErrors(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// wantErr is how the error message starts: for a malformed date, the
|
|
// date parser's own explanation follows it.
|
|
tests := []struct {
|
|
name string
|
|
date string
|
|
from string
|
|
to string
|
|
wantErr string
|
|
}{
|
|
{
|
|
name: "from after to", from: "2026-03-02", to: "2026-03-01",
|
|
wantErr: "--from 2026-03-02 is after --to 2026-03-01",
|
|
},
|
|
{name: "from without to", from: "2026-04-01", wantErr: "--from requires --to"},
|
|
{name: "to without from", to: "2026-04-02", wantErr: "--to requires --from"},
|
|
{
|
|
name: "date with from", date: "2026-01-05", from: "2026-01-06",
|
|
wantErr: "--date and --from/--to are mutually exclusive",
|
|
},
|
|
{
|
|
name: "date with from and to", date: "2026-01-07",
|
|
from: "2026-01-08", to: "2026-01-09",
|
|
wantErr: "--date and --from/--to are mutually exclusive",
|
|
},
|
|
{
|
|
name: "malformed date", date: "27.06.2026",
|
|
wantErr: `invalid --date "27.06.2026" (expected YYYY-MM-DD): `,
|
|
},
|
|
{
|
|
name: "date that does not exist", date: "2026-02-30",
|
|
wantErr: `invalid --date "2026-02-30" (expected YYYY-MM-DD): `,
|
|
},
|
|
{
|
|
name: "malformed from", from: "2026-1-10", to: "2026-01-11",
|
|
wantErr: `invalid --from "2026-1-10" (expected YYYY-MM-DD): `,
|
|
},
|
|
{
|
|
name: "malformed to", from: "2026-01-12", to: "tomorrow",
|
|
wantErr: `invalid --to "tomorrow" (expected YYYY-MM-DD): `,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := cli.ParseTargetDates(tt.date, tt.from, tt.to)
|
|
if err == nil || !strings.HasPrefix(err.Error(), tt.wantErr) {
|
|
t.Errorf("error = %v, want one starting %q", err, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|