Add internal/services/membership package: AttendanceLoader, TransactionLoader, ExceptionLoader interfaces + NewStubSources stub (returns ErrIOPending until M4 lands real Sheets loaders). FeesReport and ReconcileReport orchestrate domain/fees + domain/reconcile and write fixed-width text reports matching Python calculate_fees.py and match_payments.py print_report output. 13 unit tests cover all formatter branches and orchestration wiring via fake loaders. cmd/fuj/main.go: fees and reconcile subcommands now dispatch; sync/infer retain the [M4] placeholder. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
28 lines
608 B
Go
28 lines
608 B
Go
package membership
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
func TestStubLoaderReturnsErrIOPending(t *testing.T) {
|
|
t.Parallel()
|
|
s := NewStubSources()
|
|
|
|
_, _, err := s.LoadAdults(context.Background())
|
|
if !errors.Is(err, ErrIOPending) {
|
|
t.Errorf("LoadAdults: want ErrIOPending, got %v", err)
|
|
}
|
|
|
|
_, err = s.LoadTransactions(context.Background())
|
|
if !errors.Is(err, ErrIOPending) {
|
|
t.Errorf("LoadTransactions: want ErrIOPending, got %v", err)
|
|
}
|
|
|
|
_, err = s.LoadExceptions(context.Background())
|
|
if !errors.Is(err, ErrIOPending) {
|
|
t.Errorf("LoadExceptions: want ErrIOPending, got %v", err)
|
|
}
|
|
}
|