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 @@
+ [1m Benchmark-0 [0m main (1234567)
+---------------------------------------------
+ [1mNumber of iterations[0m 1 000
+ [1mNanoseconds per iteration[0m 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 @@
+ [1m Benchmark-1 [0m main (1234567)
+---------------------------------------------
+ [1mNumber of iterations[0m 1,500
+ [1mNanoseconds per iteration[0m 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 |