diff --git a/ana/prediction_test.go b/ana/prediction_test.go index d3544c2..61a9db7 100644 --- a/ana/prediction_test.go +++ b/ana/prediction_test.go @@ -1,7 +1,6 @@ package ana import ( - "fmt" "maps" "testing" "time" @@ -31,8 +30,12 @@ func TestPredictionPredict(t *testing.T) { return result } from := time.Now() + month := time.Hour * 24 * 365 / 12 these := []time.Time{time.Now().Add(time.Hour * 24 * 365 / 12)} theseK := these[0].Format("2006-01") + thisMonth := time.Now().Add(-1 * time.Duration(time.Now().Day()) * time.Hour * 24) + monthsAgo1 := thisMonth.Add(-1 * month).Format("2006-01") + monthsAgo2 := thisMonth.Add(-2 * month).Format("2006-01") _, _ = inc, double cases := map[string]struct { @@ -63,14 +66,55 @@ func TestPredictionPredict(t *testing.T) { given: ledger.Balances{"X": ledger.Balance{"X": 5}}, want: ledger.Register{theseK: ledger.Balances{"X": ledger.Balance{"X": 11}}}, }, + "contribution": { + prediction: Prediction{ + NewContributionPredictor(ledger.Register{ + "2001-01": ledger.Balances{"X": ledger.Balance{"X": 100}}, // too old + "2001-02": ledger.Balances{"X": ledger.Balance{"X": 10000}}, // too old + monthsAgo2: ledger.Balances{"X": ledger.Balance{"X": 100}}, + monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 600}}, // +500 once in 6 months + }), + }, + given: ledger.Balances{"X": ledger.Balance{"X": 5}}, + want: ledger.Register{theseK: ledger.Balances{"X": ledger.Balance{"X": 105}}}, + }, + "interest": { + prediction: Prediction{ + NewInterestPredictor("X", "X", 12), + }, + given: ledger.Balances{"X": ledger.Balance{"X": 5}}, + want: ledger.Register{theseK: ledger.Balances{"X": ledger.Balance{"X": 10}}}, + }, + "interest, contribution": { + prediction: Prediction{ + NewInterestPredictor("X", "X", 12), + NewContributionPredictor(ledger.Register{ + monthsAgo2: ledger.Balances{"X": ledger.Balance{"X": 100}}, + monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 600}}, + }), + }, + given: ledger.Balances{"X": ledger.Balance{"X": 5}}, + want: ledger.Register{theseK: ledger.Balances{"X": ledger.Balance{"X": 110}}}, + }, + "contribution, interest": { + prediction: Prediction{ + NewContributionPredictor(ledger.Register{ + monthsAgo2: ledger.Balances{"X": ledger.Balance{"X": 100}}, + monthsAgo1: ledger.Balances{"X": ledger.Balance{"X": 600}}, + }), + NewInterestPredictor("X", "X", 12), + }, + given: ledger.Balances{"X": ledger.Balance{"X": 5}}, + want: ledger.Register{theseK: ledger.Balances{"X": ledger.Balance{"X": 210}}}, + }, } for name, d := range cases { c := d t.Run(name, func(t *testing.T) { got := c.prediction.predict(c.given, from, these) - if fmt.Sprintf("%+v", got) != fmt.Sprintf("%+v", c.want) { - t.Errorf("want\n\t%+v, got\n\t%+v", c.want, got) + if got.Debug() != c.want.Debug() { + t.Errorf("want\n\t%+v, got\n\t%+v", c.want.Debug(), got.Debug()) } }) } diff --git a/ledger/register.go b/ledger/register.go index b223c7d..a72cec6 100644 --- a/ledger/register.go +++ b/ledger/register.go @@ -100,3 +100,19 @@ func dateToTime(s string) (time.Time, error) { } return time.Time{}, fmt.Errorf("no layout matching %q", s) } + +func (register Register) Debug() string { + result := "{" + for _, date := range register.Dates() { + result += "{" + date + for name, balance := range register[date] { + result += "{" + name + for cur, v := range balance { + result += fmt.Sprintf("%s=%.2f ", cur, v) + } + result += "}" + } + result += "}" + } + return result + "}" +}