diff --git a/cmd/root.go b/cmd/root.go index bb6c3992..798ffb77 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -33,12 +33,12 @@ import ( "strings" "time" + "github.com/k1LoW/octocov/badge" "github.com/k1LoW/octocov/central" "github.com/k1LoW/octocov/config" "github.com/k1LoW/octocov/datastore" "github.com/k1LoW/octocov/gh" "github.com/k1LoW/octocov/internal" - "github.com/k1LoW/octocov/badge" "github.com/k1LoW/octocov/report" "github.com/k1LoW/octocov/version" "github.com/spf13/cobra" @@ -161,7 +161,7 @@ var rootCmd = &cobra.Command{ return nil } - r, err := report.New(c.Repository) + r, err := report.New(c.Repository, report.Locale(c.Locale)) if err != nil { return err } @@ -354,7 +354,7 @@ var rootCmd = &cobra.Command{ } } if c.Diff.Path != "" { - rt, err := report.New(c.Repository) + rt, err := report.New(c.Repository, report.Locale(c.Locale)) if err != nil { return err } @@ -502,7 +502,7 @@ func printMetrics(cmd *cobra.Command) error { c.CodeToTestRatio = nil c.TestExecutionTime = nil } - r, err := report.New(c.Repository) + r, err := report.New(c.Repository, report.Locale(c.Locale)) if err != nil { return err } diff --git a/config/config.go b/config/config.go index 1b537115..94b41233 100644 --- a/config/config.go +++ b/config/config.go @@ -16,7 +16,7 @@ import ( "github.com/k1LoW/duration" "github.com/k1LoW/expand" "github.com/k1LoW/octocov/gh" - "github.com/k1LoW/octocov/report" + "golang.org/x/text/language" ) const defaultBadgesDatastore = "local://reports" @@ -48,6 +48,7 @@ type Config struct { Body *Body `yaml:"body,omitempty"` Diff *Diff `yaml:"diff,omitempty"` Timeout time.Duration `yaml:"timeout,omitempty"` + Locale *language.Tag `yaml:"locale,omitempty"` GitRoot string `yaml:"-"` // working directory wd string @@ -190,23 +191,24 @@ func (c *Config) Loaded() bool { return c.path != "" } -func (c *Config) Acceptable(r, rPrev *report.Report) error { +type Reporter interface { + CoveragePercent() float64 + CodeToTestRatioRatio() float64 + TestExecutionTimeNano() float64 + IsMeasuredTestExecutionTime() bool +} + +func (c *Config) Acceptable(r, rPrev Reporter) error { var result *multierror.Error if err := c.CoverageConfigReady(); err == nil { - prev := 0.0 - if rPrev != nil { - prev = rPrev.CoveragePercent() - } + prev := rPrev.CoveragePercent() if err := coverageAcceptable(r.CoveragePercent(), prev, c.Coverage.Acceptable); err != nil { result = multierror.Append(result, err) } } if err := c.CodeToTestRatioConfigReady(); err == nil { - prev := 0.0 - if rPrev != nil { - prev = rPrev.CodeToTestRatioRatio() - } + prev := rPrev.CodeToTestRatioRatio() if err := codeToTestRatioAcceptable(r.CodeToTestRatioRatio(), prev, c.CodeToTestRatio.Acceptable); err != nil { result = multierror.Append(result, err) } @@ -214,10 +216,8 @@ func (c *Config) Acceptable(r, rPrev *report.Report) error { if err := c.TestExecutionTimeConfigReady(); err == nil { prev := largeEnoughTime - if rPrev != nil { - if rPrev.IsMeasuredTestExecutionTime() { - prev = rPrev.TestExecutionTimeNano() - } + if rPrev.IsMeasuredTestExecutionTime() { + prev = rPrev.TestExecutionTimeNano() } if err := testExecutionTimeAcceptable(r.TestExecutionTimeNano(), prev, c.TestExecutionTime.Acceptable); err != nil { diff --git a/config/config_test.go b/config/config_test.go index e0beca78..d9478fce 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + "golang.org/x/text/language" ) func TestMain(m *testing.M) { @@ -92,6 +93,40 @@ func TestLoadCentralPush(t *testing.T) { } } +func TestLoadLocale(t *testing.T) { + tests := []struct { + path string + want *language.Tag + wantError bool + }{ + {"locale_nothing.yml", nil, false}, + {"locale_empty.yml", nil, false}, + {"locale_ja.yml", &language.Japanese, false}, + {"locale_ja_uppercase.yml", &language.Japanese, false}, + {"locale_fr.yml", &language.French, false}, + {"locale_unkown.yml", nil, true}, + } + for _, tt := range tests { + c := New() + t.Run(fmt.Sprintf("%v", tt.path), func(t *testing.T) { + p := filepath.Join(testdataDir(t), tt.path) + if err := c.Load(p); err != nil { + if tt.wantError { + return + } + t.Fatal(err) + } + got := c.Locale + if tt.want == nil && got == nil { + return + } + if diff := cmp.Diff(got.String(), tt.want.String(), nil); diff != "" { + t.Error(diff) + } + }) + } +} + func TestCoveragePaths(t *testing.T) { tests := []struct { paths []string diff --git a/config/testdata/locale_empty.yml b/config/testdata/locale_empty.yml new file mode 100644 index 00000000..d1542ab8 --- /dev/null +++ b/config/testdata/locale_empty.yml @@ -0,0 +1 @@ +locale: diff --git a/config/testdata/locale_fr.yml b/config/testdata/locale_fr.yml new file mode 100644 index 00000000..448c63fa --- /dev/null +++ b/config/testdata/locale_fr.yml @@ -0,0 +1 @@ +locale: "fr" diff --git a/config/testdata/locale_ja.yml b/config/testdata/locale_ja.yml new file mode 100644 index 00000000..38422c93 --- /dev/null +++ b/config/testdata/locale_ja.yml @@ -0,0 +1 @@ +locale: "ja" diff --git a/config/testdata/locale_ja_uppercase.yml b/config/testdata/locale_ja_uppercase.yml new file mode 100644 index 00000000..646d2ec8 --- /dev/null +++ b/config/testdata/locale_ja_uppercase.yml @@ -0,0 +1 @@ +locale: "JA" diff --git a/config/testdata/locale_nothing.yml b/config/testdata/locale_nothing.yml new file mode 100644 index 00000000..e69de29b diff --git a/config/testdata/locale_unknown.yml b/config/testdata/locale_unknown.yml new file mode 100644 index 00000000..88b49b2f --- /dev/null +++ b/config/testdata/locale_unknown.yml @@ -0,0 +1 @@ +locale: "unknown" diff --git a/config/yaml.go b/config/yaml.go index eef227ab..fd29c81e 100644 --- a/config/yaml.go +++ b/config/yaml.go @@ -5,6 +5,7 @@ import ( "github.com/goccy/go-yaml" "github.com/k1LoW/duration" + "golang.org/x/text/language" ) var commentRe = regexp.MustCompile(`(?m)^comment:`) @@ -25,6 +26,7 @@ func (c *Config) UnmarshalYAML(data []byte) error { Body *Body `yaml:"body,omitempty"` Diff *Diff `yaml:"diff,omitempty"` Timeout string `yaml:"timeout,omitempty"` + Locale string `yaml:"locale,omitempty"` }{} err := yaml.Unmarshal(data, &s) if err != nil { @@ -85,6 +87,15 @@ func (c *Config) UnmarshalYAML(data []byte) error { c.Push = v } + if s.Locale != "" { + l, err := language.Parse(s.Locale) + if err != nil { + return err + } + + c.Locale = &l + } + return nil } diff --git a/go.mod b/go.mod index 9a43fa45..13c1f777 100644 --- a/go.mod +++ b/go.mod @@ -46,6 +46,7 @@ require ( golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb golang.org/x/image v0.10.0 golang.org/x/oauth2 v0.7.0 + golang.org/x/text v0.14.0 golang.org/x/tools v0.13.0 google.golang.org/api v0.114.0 gopkg.in/ini.v1 v1.67.0 @@ -115,7 +116,6 @@ require ( golang.org/x/net v0.19.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.15.0 // indirect - golang.org/x/text v0.14.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect diff --git a/report/custom.go b/report/custom.go index 56a2e120..d16a5d5d 100644 --- a/report/custom.go +++ b/report/custom.go @@ -64,19 +64,17 @@ func (s *CustomMetricSet) Table() string { if len(s.Metrics) >= swapXYMin { return s.tableSwaped() } + report := s.report + if report == nil { + report = &Report{} + } var ( h []string d []string ) for _, m := range s.Metrics { h = append(h, m.Name) - var v string - if isInt(m.Value) { - v = fmt.Sprintf("%d%s", int(m.Value), m.Unit) - } else { - v = fmt.Sprintf("%.1f%s", m.Value, m.Unit) - } - d = append(d, v) + d = append(d, fmt.Sprintf("%s%s", report.convertFormat(m.Value), m.Unit)) } buf := new(bytes.Buffer) _, _ = buf.WriteString(fmt.Sprintf("## %s\n\n", s.Name)) //nostyle:handlerrors @@ -100,14 +98,10 @@ func (s *CustomMetricSet) tableSwaped() string { table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") table.SetHeader([]string{"", makeHeadTitleWithLink(s.report.Ref, s.report.Commit, nil)}) + + report := s.report for _, m := range s.Metrics { - var v string - if isInt(m.Value) { - v = fmt.Sprintf("%d%s", int(m.Value), m.Unit) - } else { - v = fmt.Sprintf("%.1f%s", m.Value, m.Unit) - } - table.Append([]string{m.Name, v}) + table.Append([]string{m.Name, fmt.Sprintf("%s%s", report.convertFormat(m.Value), m.Unit)}) } table.Render() return strings.Replace(buf.String(), "---|", "--:|", len(s.Metrics)) @@ -159,17 +153,16 @@ func (s *CustomMetricSet) Out(w io.Writer) error { table.SetBorder(false) table.SetColumnAlignment([]int{tablewriter.ALIGN_LEFT, tablewriter.ALIGN_RIGHT}) + report := s.report + if report == nil { + report = &Report{} + } + for _, m := range s.Metrics { if m.Name == "" { m.Name = m.Key } - var v string - if isInt(m.Value) { - v = fmt.Sprintf("%d%s", int(m.Value), m.Unit) - } else { - v = fmt.Sprintf("%.1f%s", m.Value, m.Unit) - } - table.Rich([]string{m.Name, v}, []tablewriter.Colors{tablewriter.Colors{tablewriter.Bold}, tablewriter.Colors{}}) + table.Rich([]string{m.Name, fmt.Sprintf("%s%s", report.convertFormat(m.Value), m.Unit)}, []tablewriter.Colors{tablewriter.Colors{tablewriter.Bold}, tablewriter.Colors{}}) } table.Render() @@ -276,6 +269,8 @@ func (d *DiffCustomMetricSet) Table() string { table.SetCenterSeparator("|") table.SetColumnAlignment([]int{tablewriter.ALIGN_LEFT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT}) table.SetHeader([]string{"", makeHeadTitleWithLink(d.B.report.Ref, d.B.report.Commit, nil), makeHeadTitleWithLink(d.A.report.Ref, d.A.report.Commit, nil), "+/-"}) + report := d.report() + for _, m := range d.Metrics { var va, vb, diff string switch { @@ -283,30 +278,20 @@ func (d *DiffCustomMetricSet) Table() string { continue case m.A != nil && m.B == nil: vb = "" - if isInt(*m.A) { - va = fmt.Sprintf("%d%s", int(*m.A), m.customMetricA.Unit) - diff = fmt.Sprintf("%d%s", int(m.Diff), m.customMetricA.Unit) - } else { - va = fmt.Sprintf("%.1f%s", *m.A, m.customMetricA.Unit) - diff = fmt.Sprintf("%.1f%s", m.Diff, m.customMetricA.Unit) - } + va = fmt.Sprintf("%s%s", report.convertFormat(*m.A), m.customMetricA.Unit) + diff = fmt.Sprintf("%s%s", report.convertFormat(m.Diff), m.customMetricA.Unit) case m.A == nil && m.B != nil: va = "" - if isInt(*m.B) { - vb = fmt.Sprintf("%d%s", int(*m.B), m.customMetricB.Unit) - diff = fmt.Sprintf("%d%s", int(m.Diff), m.customMetricB.Unit) - } else { - vb = fmt.Sprintf("%.1f%s", *m.B, m.customMetricB.Unit) - diff = fmt.Sprintf("%.1f%s", m.Diff, m.customMetricB.Unit) - } + vb = fmt.Sprintf("%s%s", report.convertFormat(*m.B), m.customMetricB.Unit) + diff = fmt.Sprintf("%s%s", report.convertFormat(m.Diff), m.customMetricB.Unit) case isInt(*m.A) && isInt(*m.B): - va = fmt.Sprintf("%d%s", int(*m.A), m.customMetricA.Unit) - vb = fmt.Sprintf("%d%s", int(*m.B), m.customMetricB.Unit) - diff = fmt.Sprintf("%d%s", int(m.Diff), m.customMetricA.Unit) + va = fmt.Sprintf("%s%s", report.convertFormat(*m.A), m.customMetricA.Unit) + vb = fmt.Sprintf("%s%s", report.convertFormat(*m.B), m.customMetricB.Unit) + diff = fmt.Sprintf("%s%s", report.convertFormat(m.Diff), m.customMetricA.Unit) default: - va = fmt.Sprintf("%.1f%s", *m.A, m.customMetricA.Unit) - vb = fmt.Sprintf("%.1f%s", *m.B, m.customMetricB.Unit) - diff = fmt.Sprintf("%.1f%s", m.Diff, m.customMetricA.Unit) + va = fmt.Sprintf("%s%s", report.convertFormat(*m.A), m.customMetricA.Unit) + vb = fmt.Sprintf("%s%s", report.convertFormat(*m.B), m.customMetricB.Unit) + diff = fmt.Sprintf("%s%s", report.convertFormat(m.Diff), m.customMetricA.Unit) } if m.Name == "" { m.Name = m.Key @@ -350,6 +335,17 @@ func (d *DiffCustomMetricSet) MetadataTable() string { return strings.Replace(strings.Replace(buf.String(), "---|", "--:|", 4), "--:|", "---|", 1) } +func (d *DiffCustomMetricSet) report() *Report { + if d.A != nil && d.A.report != nil { + return d.A.report + } + if d.B != nil && d.B.report != nil { + return d.B.report + } + + return &Report{} +} + func isInt(v float64) bool { return v == float64(int64(v)) } diff --git a/report/custom_test.go b/report/custom_test.go index f6ffcb67..5fc4cdce 100644 --- a/report/custom_test.go +++ b/report/custom_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/tenntenn/golden" + "golang.org/x/text/language" ) func TestCustomMetricSetTable(t *testing.T) { @@ -47,6 +48,45 @@ func TestCustomMetricSetTable(t *testing.T) { covPaths: []string{"testdata/cover.out"}, }, }}, + {&CustomMetricSet{ + Key: "benchmark_0", + Name: "Benchmark-0", + Metrics: []*CustomMetric{ + {Key: "N", Name: "Number of iterations", Value: 1000.0, Unit: ""}, + {Key: "NsPerOp", Name: "Nanoseconds per iteration", Value: 676.5, Unit: " ns/op"}, + }, + report: &Report{ + opts: &Options{Locale: &language.French}, + }, + }}, + {&CustomMetricSet{ + Key: "benchmark_1", + Name: "Benchmark-1", + Metrics: []*CustomMetric{ + {Key: "N", Name: "Number of iterations", Value: 1500.0, Unit: ""}, + {Key: "NsPerOp", Name: "Nanoseconds per iteration", Value: 1340.0, Unit: " ns/op"}, + }, + report: &Report{ + opts: &Options{Locale: &language.Japanese}, + }, + }}, + {&CustomMetricSet{ + Key: "many_metrics", + Name: "Many Metrics", + Metrics: []*CustomMetric{ + {Key: "A", Name: "Metrics A", Value: 1500.0, Unit: ""}, + {Key: "B", Name: "Metrics B", Value: 1340.0, Unit: ""}, + {Key: "C", Name: "Metrics C", Value: 1600.0, Unit: ""}, + {Key: "D", Name: "Metrics D", Value: 1010.0, Unit: ""}, + {Key: "E", Name: "Metrics E", Value: 1800.0, Unit: ""}, + }, + report: &Report{ + Ref: "main", + Commit: "1234567890", + covPaths: []string{"testdata/cover.out"}, + opts: &Options{Locale: &language.French}, + }, + }}, } t.Setenv("GITHUB_SERVER_URL", "https://github.com") t.Setenv("GITHUB_REPOSITORY", "owner/repo") @@ -127,6 +167,34 @@ func TestCustomMetricSetOut(t *testing.T) { covPaths: []string{"testdata/cover.out"}, }, }}, + {&CustomMetricSet{ + Key: "benchmark_0", + Name: "Benchmark-0", + Metrics: []*CustomMetric{ + {Key: "N", Name: "Number of iterations", Value: 1000.0, Unit: ""}, + {Key: "NsPerOp", Name: "Nanoseconds per iteration", Value: 676.5, Unit: " ns/op"}, + }, + report: &Report{ + Ref: "main", + Commit: "1234567890", + covPaths: []string{"testdata/cover.out"}, + opts: &Options{Locale: &language.French}, + }, + }}, + {&CustomMetricSet{ + Key: "benchmark_1", + Name: "Benchmark-1", + Metrics: []*CustomMetric{ + {Key: "N", Name: "Number of iterations", Value: 1500.0, Unit: ""}, + {Key: "NsPerOp", Name: "Nanoseconds per iteration", Value: 1340.0, Unit: " ns/op"}, + }, + report: &Report{ + Ref: "main", + Commit: "1234567890", + covPaths: []string{"testdata/cover.out"}, + opts: &Options{Locale: &language.Japanese}, + }, + }}, } for i, tt := range tests { t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { @@ -255,6 +323,52 @@ func TestDiffCustomMetricSetTable(t *testing.T) { }, }, }, + { + &CustomMetricSet{ + Key: "benchmark_0", + Name: "Benchmark-0", + Metrics: []*CustomMetric{ + {Key: "N", Name: "Number of iterations", Value: 1000.0, Unit: ""}, + {Key: "NsPerOp", Name: "Nanoseconds per iteration", Value: 676.5, Unit: " ns/op"}, + }, + report: &Report{ + Ref: "main", + Commit: "1234567890", + covPaths: []string{"testdata/cover.out"}, + opts: &Options{Locale: &language.French}, + }, + }, + nil, + }, + { + &CustomMetricSet{ + Key: "benchmark_0", + Name: "Benchmark-0", + Metrics: []*CustomMetric{ + {Key: "N", Name: "Number of iterations", Value: 1000.0, Unit: ""}, + {Key: "NsPerOp", Name: "Nanoseconds per iteration", Value: 676.5, Unit: " ns/op"}, + }, + report: &Report{ + Ref: "main", + Commit: "1234567890", + covPaths: []string{"testdata/cover.out"}, + opts: &Options{Locale: &language.Japanese}, + }, + }, + &CustomMetricSet{ + Key: "benchmark_0", + Name: "Benchmark-0", + Metrics: []*CustomMetric{ + {Key: "N", Name: "Number of iterations", Value: 9393.0, Unit: ""}, + {Key: "NsPerOp", Name: "Nanoseconds per iteration", Value: 456.0, Unit: " ns/op"}, + }, + report: &Report{ + Ref: "main", + Commit: "2345678901", + covPaths: []string{"testdata/cover.out"}, + }, + }, + }, } t.Setenv("GITHUB_SERVER_URL", "https://github.com") @@ -324,6 +438,52 @@ func TestDiffCustomMetricSetMetadataTable(t *testing.T) { }, }, }, + { + &CustomMetricSet{ + Key: "benchmark_0", + Name: "Benchmark-0", + Metadata: []*MetadataKV{ + {Key: "goos", Value: "darwin"}, + {Key: "goarch", Value: "amd64"}, + }, + report: &Report{ + Ref: "main", + Commit: "1234567890", + covPaths: []string{"testdata/cover.out"}, + opts: &Options{Locale: &language.French}, + }, + }, + nil, + }, + { + &CustomMetricSet{ + Key: "benchmark_0", + Name: "Benchmark-0", + Metadata: []*MetadataKV{ + {Key: "goos", Value: "darwin"}, + {Key: "goarch", Value: "amd64"}, + }, + report: &Report{ + Ref: "main", + Commit: "1234567890", + covPaths: []string{"testdata/cover.out"}, + opts: &Options{Locale: &language.Japanese}, + }, + }, + &CustomMetricSet{ + Key: "benchmark_0", + Name: "Benchmark-0", + Metadata: []*MetadataKV{ + {Key: "goos", Value: "arwin"}, + {Key: "goarch", Value: "arm64"}, + }, + report: &Report{ + Ref: "main", + Commit: "2345678901", + covPaths: []string{"testdata/cover.out"}, + }, + }, + }, } t.Setenv("GITHUB_SERVER_URL", "https://github.com") diff --git a/report/option.go b/report/option.go new file mode 100644 index 00000000..6d07689f --- /dev/null +++ b/report/option.go @@ -0,0 +1,15 @@ +package report + +import "golang.org/x/text/language" + +type Options struct { + Locale *language.Tag +} + +type Option func(*Options) + +func Locale(locale *language.Tag) Option { + return func(args *Options) { + args.Locale = locale + } +} diff --git a/report/report.go b/report/report.go index 123c627a..2dc37074 100644 --- a/report/report.go +++ b/report/report.go @@ -16,16 +16,23 @@ import ( "github.com/goccy/go-json" "github.com/hashicorp/go-multierror" - "github.com/k1LoW/octocov/gh" + "github.com/k1LoW/octocov/config" "github.com/k1LoW/octocov/coverage" + "github.com/k1LoW/octocov/gh" "github.com/k1LoW/octocov/ratio" "github.com/olekukonko/tablewriter" "github.com/samber/lo" + "golang.org/x/text/message" + "golang.org/x/text/number" ) const filesHideMin = 30 const filesSkipMax = 100 +var ( + _ config.Reporter = (*Report)(nil) +) + type Report struct { Repository string `json:"repository"` Ref string `json:"ref"` @@ -38,9 +45,10 @@ type Report struct { // coverage report paths covPaths []string + opts *Options } -func New(ownerrepo string) (*Report, error) { +func New(ownerrepo string, opts ...Option) (*Report, error) { if ownerrepo == "" { ownerrepo = os.Getenv("GITHUB_REPOSITORY") } @@ -60,12 +68,17 @@ func New(ownerrepo string) (*Report, error) { commit = strings.TrimSuffix(string(b), "\n") } } + o := &Options{} + for _, setter := range opts { + setter(o) + } return &Report{ Repository: ownerrepo, Ref: ref, Commit: commit, Timestamp: time.Now().UTC(), + opts: o, }, nil } @@ -258,6 +271,9 @@ func (r *Report) IsMeasuredCodeToTestRatio() bool { } func (r *Report) IsMeasuredTestExecutionTime() bool { + if r == nil { + return false + } return r.TestExecutionTime != nil } @@ -447,21 +463,21 @@ func (r *Report) CollectCustomMetrics() error { } func (r *Report) CoveragePercent() float64 { - if r.Coverage == nil || r.Coverage.Total == 0 { + if r == nil || r.Coverage == nil || r.Coverage.Total == 0 { return 0.0 } return float64(r.Coverage.Covered) / float64(r.Coverage.Total) * 100 } func (r *Report) CodeToTestRatioRatio() float64 { - if r.CodeToTestRatio == nil || r.CodeToTestRatio.Code == 0 { + if r == nil || r.CodeToTestRatio == nil || r.CodeToTestRatio.Code == 0 { return 0.0 } return float64(r.CodeToTestRatio.Test) / float64(r.CodeToTestRatio.Code) } func (r *Report) TestExecutionTimeNano() float64 { - if r.TestExecutionTime == nil { + if r == nil || r.TestExecutionTime == nil { return 0.0 } return *r.TestExecutionTime @@ -538,6 +554,25 @@ func (r *Report) findCustomMetricSetByKey(key string) *CustomMetricSet { return nil } +func (r *Report) convertFormat(v any) string { + if r.opts != nil && r.opts.Locale != nil { + p := message.NewPrinter(*r.opts.Locale) + return p.Sprint(number.Decimal(v)) + } + + switch vv := v.(type) { + case int, int8, int16, int32, int64: + return fmt.Sprintf("%d", vv) + case float64: + if isInt(vv) { + return fmt.Sprintf("%d", int(vv)) + } + return fmt.Sprintf("%.1f", vv) + default: + panic(fmt.Errorf("convert format error .Unknown type:%v", vv)) + } +} + func makeHeadTitle(ref, commit string, covPaths []string) string { ref = strings.TrimPrefix(ref, "refs/heads/") if strings.HasPrefix(ref, "refs/pull/") { diff --git a/report/report_test.go b/report/report_test.go index df3e1a44..156ab001 100644 --- a/report/report_test.go +++ b/report/report_test.go @@ -16,6 +16,7 @@ import ( "github.com/k1LoW/octocov/coverage" "github.com/k1LoW/octocov/gh" "github.com/k1LoW/octocov/ratio" + "golang.org/x/text/language" ) func TestNew(t *testing.T) { @@ -43,6 +44,29 @@ func TestNew(t *testing.T) { } } +func TestNewWithOptions(t *testing.T) { + tests := []struct { + opts []Option + want *language.Tag + }{ + {nil, nil}, + {[]Option{Locale(&language.Japanese)}, &language.Japanese}, + {[]Option{Locale(&language.French)}, &language.French}, + {[]Option{Locale(&language.Japanese), Locale(&language.French)}, &language.French}, // Be overwritten + } + for _, tt := range tests { + r, err := New("somthing", tt.opts...) + if err != nil { + t.Error(err) + continue + } + got := r.opts.Locale + if got != tt.want { + t.Errorf("got %v\nwant %v", got, tt.want) + } + } +} + func TestMeasureCoverage(t *testing.T) { log.SetOutput(io.Discard) // Disable log in challengeParseReport() @@ -536,3 +560,43 @@ func coverageTestdataDir(t *testing.T) string { } return dir } + +func TestConvertFormat(t *testing.T) { + tests := []struct { + n any + want string + }{ + { + int(10), + "10", + }, + { + int32(3200), + "3,200", + }, + { + float32(10.0), + "10", + }, + { + float32(1000.1), + "1,000.1", + }, + { + int(1000), + "1,000", + }, + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + l := language.Japanese + r := &Report{opts: &Options{Locale: &l}} + + got := r.convertFormat(tt.n) + if diff := cmp.Diff(got, tt.want, nil); diff != "" { + t.Error(diff) + } + }) + } +} diff --git a/testdata/custom_metrics/custom_metric_set_out.3.golden b/testdata/custom_metrics/custom_metric_set_out.3.golden new file mode 100644 index 00000000..44e225e0 --- /dev/null +++ b/testdata/custom_metrics/custom_metric_set_out.3.golden @@ -0,0 +1,4 @@ +  Benchmark-0  main (1234567) +--------------------------------------------- + Number of iterations 1 000 + Nanoseconds per iteration 676,5 ns/op diff --git a/testdata/custom_metrics/custom_metric_set_out.4.golden b/testdata/custom_metrics/custom_metric_set_out.4.golden new file mode 100644 index 00000000..ece4782e --- /dev/null +++ b/testdata/custom_metrics/custom_metric_set_out.4.golden @@ -0,0 +1,4 @@ +  Benchmark-1  main (1234567) +--------------------------------------------- + Number of iterations 1,500 + Nanoseconds per iteration 1,340 ns/op diff --git a/testdata/custom_metrics/custom_metric_set_table.4.golden b/testdata/custom_metrics/custom_metric_set_table.4.golden new file mode 100644 index 00000000..342a0952 --- /dev/null +++ b/testdata/custom_metrics/custom_metric_set_table.4.golden @@ -0,0 +1,5 @@ +## Benchmark-0 + +| Number of iterations | Nanoseconds per iteration | +|---------------------:|--------------------------:| +| 1 000 | 676,5 ns/op | diff --git a/testdata/custom_metrics/custom_metric_set_table.5.golden b/testdata/custom_metrics/custom_metric_set_table.5.golden new file mode 100644 index 00000000..fd776ac5 --- /dev/null +++ b/testdata/custom_metrics/custom_metric_set_table.5.golden @@ -0,0 +1,5 @@ +## Benchmark-1 + +| Number of iterations | Nanoseconds per iteration | +|---------------------:|--------------------------:| +| 1,500 | 1,340 ns/op | diff --git a/testdata/custom_metrics/custom_metric_set_table.6.golden b/testdata/custom_metrics/custom_metric_set_table.6.golden new file mode 100644 index 00000000..f62e1f92 --- /dev/null +++ b/testdata/custom_metrics/custom_metric_set_table.6.golden @@ -0,0 +1,9 @@ +## Many Metrics + +| | main ([1234567](https://github.com/owner/repo/commit/1234567890)) | +|----------:|------------------------------------------------------------------:| +| Metrics A | 1 500 | +| Metrics B | 1 340 | +| Metrics C | 1 600 | +| Metrics D | 1 010 | +| Metrics E | 1 800 | diff --git a/testdata/custom_metrics/diff_custom_metric_set_metadata_table.2.golden b/testdata/custom_metrics/diff_custom_metric_set_metadata_table.2.golden new file mode 100644 index 00000000..4185c6be --- /dev/null +++ b/testdata/custom_metrics/diff_custom_metric_set_metadata_table.2.golden @@ -0,0 +1,7 @@ +
Metadata + +| goos | goarch | +|-------:|-------:| +| darwin | amd64 | + +
diff --git a/testdata/custom_metrics/diff_custom_metric_set_metadata_table.3.golden b/testdata/custom_metrics/diff_custom_metric_set_metadata_table.3.golden new file mode 100644 index 00000000..4c81fd70 --- /dev/null +++ b/testdata/custom_metrics/diff_custom_metric_set_metadata_table.3.golden @@ -0,0 +1,8 @@ +
Metadata + +| | main ([2345678](https://github.com/owner/repo/commit/2345678901)) | main ([1234567](https://github.com/owner/repo/commit/1234567890)) | +|------------|------------------------------------------------------------------:|------------------------------------------------------------------:| +| **goos** | arwin | darwin | +| **goarch** | arm64 | amd64 | + +
diff --git a/testdata/custom_metrics/diff_custom_metric_set_table.1.golden b/testdata/custom_metrics/diff_custom_metric_set_table.1.golden index 8a078aa4..4f887783 100644 --- a/testdata/custom_metrics/diff_custom_metric_set_table.1.golden +++ b/testdata/custom_metrics/diff_custom_metric_set_table.1.golden @@ -3,4 +3,4 @@ | | main ([2345678](https://github.com/owner/repo/commit/2345678901)) | main ([1234567](https://github.com/owner/repo/commit/1234567890)) | +/- | |-------------------------------|------------------------------------------------------------------:|------------------------------------------------------------------:|------------:| | **Number of iterations** | 9393 | 1000 | -8393 | -| **Nanoseconds per iteration** | 456.0 ns/op | 676.5 ns/op | 220.5 ns/op | +| **Nanoseconds per iteration** | 456 ns/op | 676.5 ns/op | 220.5 ns/op | diff --git a/testdata/custom_metrics/diff_custom_metric_set_table.2.golden b/testdata/custom_metrics/diff_custom_metric_set_table.2.golden new file mode 100644 index 00000000..342a0952 --- /dev/null +++ b/testdata/custom_metrics/diff_custom_metric_set_table.2.golden @@ -0,0 +1,5 @@ +## Benchmark-0 + +| Number of iterations | Nanoseconds per iteration | +|---------------------:|--------------------------:| +| 1 000 | 676,5 ns/op | diff --git a/testdata/custom_metrics/diff_custom_metric_set_table.3.golden b/testdata/custom_metrics/diff_custom_metric_set_table.3.golden new file mode 100644 index 00000000..235b7d29 --- /dev/null +++ b/testdata/custom_metrics/diff_custom_metric_set_table.3.golden @@ -0,0 +1,6 @@ +## Benchmark-0 + +| | main ([2345678](https://github.com/owner/repo/commit/2345678901)) | main ([1234567](https://github.com/owner/repo/commit/1234567890)) | +/- | +|-------------------------------|------------------------------------------------------------------:|------------------------------------------------------------------:|------------:| +| **Number of iterations** | 9,393 | 1,000 | -8,393 | +| **Nanoseconds per iteration** | 456 ns/op | 676.5 ns/op | 220.5 ns/op |