Compare commits
4 Commits
21147954cb
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4626f08b9c | |||
| 0d97432c6c | |||
| 10e1e99683 | |||
| 38db50b879 |
@@ -4,6 +4,7 @@ import (
|
|||||||
"embed"
|
"embed"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
@@ -38,9 +39,14 @@ func NewLocalizer(lang string) (*Localizer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t Localizer) Translate(key string, count int, values map[string]any) string {
|
func (t Localizer) Translate(key string, count int, values map[string]any) string {
|
||||||
return t.MustLocalize(&i18n.LocalizeConfig{
|
txt, err := t.Localize(&i18n.LocalizeConfig{
|
||||||
MessageID: key,
|
MessageID: key,
|
||||||
TemplateData: values,
|
TemplateData: values,
|
||||||
PluralCount: count,
|
PluralCount: count,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to translate message", slog.Any("err", err))
|
||||||
|
return "<ERROR>"
|
||||||
|
}
|
||||||
|
return txt
|
||||||
}
|
}
|
||||||
|
|||||||
24
cmd/any2anexoj-cli/localizer_test.go
Normal file
24
cmd/any2anexoj-cli/localizer_test.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestNewLocalizer(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
lang string
|
||||||
|
}{
|
||||||
|
{"english", "en"},
|
||||||
|
{"portuguese", "pt"},
|
||||||
|
{"english with region", "en-US"},
|
||||||
|
{"portuguese with region", "pt-BR"},
|
||||||
|
{"unknown language falls back to default", "!!"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := NewLocalizer(tt.lang)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("want success call but failed: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1,84 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/nmoniz/any2anexoj/internal"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPrettyPrinter_Render(t *testing.T) {
|
||||||
|
// Create test data
|
||||||
|
aw := internal.NewAggregatorWriter()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Add some sample report items
|
||||||
|
err := aw.Write(ctx, internal.ReportItem{
|
||||||
|
Symbol: "AAPL",
|
||||||
|
Nature: internal.NatureG01,
|
||||||
|
BrokerCountry: 826, // United Kingdom
|
||||||
|
AssetCountry: 840, // United States
|
||||||
|
BuyValue: decimal.NewFromFloat(100.50),
|
||||||
|
BuyTimestamp: time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
|
||||||
|
SellValue: decimal.NewFromFloat(150.75),
|
||||||
|
SellTimestamp: time.Date(2023, 6, 20, 0, 0, 0, 0, time.UTC),
|
||||||
|
Fees: decimal.NewFromFloat(2.50),
|
||||||
|
Taxes: decimal.NewFromFloat(5.00),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to write first report item: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = aw.Write(ctx, internal.ReportItem{
|
||||||
|
Symbol: "GOOGL",
|
||||||
|
Nature: internal.NatureG20,
|
||||||
|
BrokerCountry: 826, // United Kingdom
|
||||||
|
AssetCountry: 840, // United States
|
||||||
|
BuyValue: decimal.NewFromFloat(200.00),
|
||||||
|
BuyTimestamp: time.Date(2023, 3, 10, 0, 0, 0, 0, time.UTC),
|
||||||
|
SellValue: decimal.NewFromFloat(225.50),
|
||||||
|
SellTimestamp: time.Date(2023, 9, 5, 0, 0, 0, 0, time.UTC),
|
||||||
|
Fees: decimal.NewFromFloat(3.00),
|
||||||
|
Taxes: decimal.NewFromFloat(7.50),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to write second report item: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create English localizer
|
||||||
|
localizer, err := NewLocalizer("en")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create localizer: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create pretty printer with buffer
|
||||||
|
var buf bytes.Buffer
|
||||||
|
pp := NewPrettyPrinter(&buf, localizer)
|
||||||
|
|
||||||
|
// Render the table
|
||||||
|
pp.Render(aw)
|
||||||
|
|
||||||
|
// Get the output
|
||||||
|
got := buf.String()
|
||||||
|
|
||||||
|
// Expected output
|
||||||
|
want := `┌───┬────────────────────────────┬───────────────────────────────────┬───────────────────────────────────┬──────────────────────────────────────────────────────────┐
|
||||||
|
│ │ │ REALIZATION │ ACQUISITION │ │
|
||||||
|
│ │ SOURCE COUNTRY │ CODE │ YEAR │ MONTH │ DAY │ VALUE │ YEAR │ MONTH │ DAY │ VALUE │ EXPENSES AND CH │ TAX PAID ABROAD │ COUNTER COUNTRY │
|
||||||
|
│ │ │ │ │ │ │ │ │ │ │ │ ARGES │ │ │
|
||||||
|
├───┼─────────────────────┼──────┼──────┼───────┼─────┼──────────────┼──────┼───────┼─────┼──────────────┼─────────────────┼─────────────────┼──────────────────────┤
|
||||||
|
│ 1 │ 840 - United States │ G01 │ 2023 │ 6 │ 20 │ 150.75 € │ 2023 │ 1 │ 15 │ 100.50 € │ 2.50 € │ 5.00 € │ 826 - United Kingdom │
|
||||||
|
│ 2 │ 840 - United States │ G20 │ 2023 │ 9 │ 5 │ 225.50 € │ 2023 │ 3 │ 10 │ 200.00 € │ 3.00 € │ 7.50 € │ 826 - United Kingdom │
|
||||||
|
├───┼─────────────────────┴──────┴──────┴───────┴─────┼──────────────┼──────┴───────┴─────┼──────────────┼─────────────────┼─────────────────┼──────────────────────┤
|
||||||
|
│ │ SUM │ 376.25 € │ │ 300.5 € │ 5.5 € │ 12.5 € │ │
|
||||||
|
└───┴─────────────────────────────────────────────────┴──────────────┴────────────────────┴──────────────┴─────────────────┴─────────────────┴──────────────────────┘
|
||||||
|
`
|
||||||
|
|
||||||
|
// Compare output
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("PrettyPrinter.Render() output doesn't match expected.\n\nGot:\n%s\n\nWant:\n%s", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ func TestAggregatorWriter_Items(t *testing.T) {
|
|||||||
aw := &internal.AggregatorWriter{}
|
aw := &internal.AggregatorWriter{}
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
for range 10 {
|
for range 5 {
|
||||||
item := internal.ReportItem{Symbol: "TEST"}
|
item := internal.ReportItem{Symbol: "TEST"}
|
||||||
if err := aw.Write(ctx, item); err != nil {
|
if err := aw.Write(ctx, item); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
@@ -226,6 +226,17 @@ func TestAggregatorWriter_Items(t *testing.T) {
|
|||||||
if count != 5 {
|
if count != 5 {
|
||||||
t.Errorf("expected for loop to stop at 5 items, got %d", count)
|
t.Errorf("expected for loop to stop at 5 items, got %d", count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for range aw.Iter() {
|
||||||
|
count++
|
||||||
|
if count == 3 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if count != 3 {
|
||||||
|
t.Errorf("expected for loop to stop at 3 items, got %d", count)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAggregatorWriter_ThreadSafety(t *testing.T) {
|
func TestAggregatorWriter_ThreadSafety(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user