Skip to content

Commit

Permalink
feat: new config lang to render numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
lucassabreu committed Jun 5, 2024
1 parent 42defda commit 66227eb
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- new config `lang` to allow setting the number format to be used when printing

## [v0.52.0] - 2024-06-02

### Added
Expand Down
83 changes: 82 additions & 1 deletion internal/mocks/mock_Config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions internal/mocks/simple_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mocks

import (
"github.com/lucassabreu/clockify-cli/pkg/cmdutil"
"golang.org/x/text/language"
)

// SimpleConfig is used to set configs for tests were changing the config or
Expand All @@ -22,6 +23,7 @@ type SimpleConfig struct {
LogLevelValue string
AllowArchivedTags bool
SearchProjectWithClientsName bool
LanguageTag language.Tag
}

// IsSearchProjectWithClientsName defines if the project name for ID should
Expand Down Expand Up @@ -125,6 +127,14 @@ func (d *SimpleConfig) GetWorkWeekdays() []string {
return d.WorkweekDays
}

func (d *SimpleConfig) SetLanguage(l language.Tag) {
d.LanguageTag = l
}

func (d *SimpleConfig) Language() language.Tag {
return d.LanguageTag
}

func (*SimpleConfig) Get(_ string) interface{} {
panic("should not call")
}
Expand Down
31 changes: 31 additions & 0 deletions pkg/cmd/config/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"github.com/lucassabreu/clockify-cli/api"
"github.com/lucassabreu/clockify-cli/pkg/cmdutil"
"github.com/lucassabreu/clockify-cli/pkg/ui"
"github.com/lucassabreu/clockify-cli/strhlp"
"github.com/spf13/cobra"
"golang.org/x/text/language"
)

func NewCmdInit(f cmdutil.Factory) *cobra.Command {
Expand Down Expand Up @@ -179,6 +181,35 @@ func NewCmdInit(f cmdutil.Factory) *cobra.Command {
return err
}

suggestLanguages := []string{
language.English.String(),
language.German.String(),
language.Afrikaans.String(),
language.Chinese.String(),
language.Portuguese.String(),
}

lang, err := i.AskForValidText("What is your preferred language:",
func(s string) error {
_, err := language.Parse(s)
return err
},
ui.WithHelp("Accepts any IETF language tag "+
"https://en.wikipedia.org/wiki/IETF_language_tag"),
ui.WithSuggestion(func(toComplete string) []string {
return strhlp.Filter(
strhlp.IsSimilar(toComplete),
suggestLanguages,
)
}),
ui.WithDefault(config.Language().String()),
)
if err != nil {
return err

Check warning on line 208 in pkg/cmd/config/init/init.go

View check run for this annotation

Codecov / codecov/patch

pkg/cmd/config/init/init.go#L208

Added line #L208 was not covered by tests
}

config.SetLanguage(language.MustParse(lang))

return config.Save()
},
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/cmd/config/init/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/lucassabreu/clockify-cli/pkg/ui"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"golang.org/x/text/language"
)

func setStringFn(config *mocks.MockConfig, name, value string) *mock.Call {
Expand Down Expand Up @@ -107,6 +108,9 @@ func TestInitCmd(t *testing.T) {

setBoolFn(config, cmdutil.CONF_ALLOW_ARCHIVED_TAGS, true, false)

config.EXPECT().Language().Return(language.English)
config.EXPECT().SetLanguage(language.German)

config.EXPECT().Save().Once().Return(nil)

f.EXPECT().UI().Return(ui.NewUI(in, out, out))
Expand Down Expand Up @@ -200,6 +204,11 @@ func TestInitCmd(t *testing.T) {
c.SendLine("n")
c.ExpectString("No")

c.ExpectString("preferred language")
c.Send("e")
c.Send(string(terminal.KeyTab))
c.SendLine(string(terminal.KeyTab))

c.ExpectEOF()
})
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/time-entry/util/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ func PrintTimeEntries(
case of.Quiet:
return output.TimeEntriesPrintQuietly(tes, out)
case of.DurationFloat:
return output.TimeEntriesTotalDurationOnlyAsFloat(tes, out)
return output.TimeEntriesTotalDurationOnlyAsFloat(
tes, out, config.Language())

Check warning on line 119 in pkg/cmd/time-entry/util/report.go

View check run for this annotation

Codecov / codecov/patch

pkg/cmd/time-entry/util/report.go#L118-L119

Added lines #L118 - L119 were not covered by tests
case of.DurationFormatted:
return output.TimeEntriesTotalDurationOnlyFormatted(tes, out)
default:
Expand Down
26 changes: 26 additions & 0 deletions pkg/cmdutil/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/lucassabreu/clockify-cli/strhlp"
"github.com/mitchellh/go-homedir"
"github.com/spf13/viper"
"golang.org/x/text/language"
)

const (
Expand All @@ -27,6 +28,7 @@ const (
CONF_LOG_LEVEL = "log-level"
CONF_ALLOW_ARCHIVED_TAGS = "allow-archived-tags"
CONF_INTERACTIVE_PAGE_SIZE = "interactive-page-size"
CONF_LANGUAGE = "lang"
)

const (
Expand Down Expand Up @@ -72,6 +74,12 @@ type Config interface {
// include the client's name
IsSearchProjectWithClientsName() bool

// Language what is the language to used when printing numbers
Language() language.Tag

// SetLanguage changes the language used for printing numbers
SetLanguage(language.Tag)

// Get retrieves a config by its name
Get(string) interface{}
// All retrieves all the configurations of the CLI as a map
Expand Down Expand Up @@ -158,6 +166,24 @@ func (c *config) IsInteractive() bool {
return c.GetBool(CONF_INTERACTIVE)
}

func (c *config) SetLanguage(l language.Tag) {
c.SetString(CONF_LANGUAGE, l.String())

Check warning on line 170 in pkg/cmdutil/config.go

View check run for this annotation

Codecov / codecov/patch

pkg/cmdutil/config.go#L169-L170

Added lines #L169 - L170 were not covered by tests
}

func (c *config) Language() language.Tag {
lang := c.GetString(CONF_LANGUAGE)
if lang == "" {
return language.English

Check warning on line 176 in pkg/cmdutil/config.go

View check run for this annotation

Codecov / codecov/patch

pkg/cmdutil/config.go#L173-L176

Added lines #L173 - L176 were not covered by tests
}

l, err := language.Parse(lang)
if err == nil {
return l

Check warning on line 181 in pkg/cmdutil/config.go

View check run for this annotation

Codecov / codecov/patch

pkg/cmdutil/config.go#L179-L181

Added lines #L179 - L181 were not covered by tests
}

return language.English

Check warning on line 184 in pkg/cmdutil/config.go

View check run for this annotation

Codecov / codecov/patch

pkg/cmdutil/config.go#L184

Added line #L184 was not covered by tests
}

func (*config) Get(p string) interface{} {
return viper.Get(p)
}
Expand Down
14 changes: 12 additions & 2 deletions pkg/output/time-entry/duration.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import (
"time"

"github.com/lucassabreu/clockify-cli/api/dto"
"golang.org/x/text/language"
"golang.org/x/text/message"
"golang.org/x/text/number"
)

func timeEntriesTotalDurationOnly(
Expand All @@ -19,9 +22,16 @@ func timeEntriesTotalDurationOnly(

// TimeEntriesTotalDurationOnlyAsFloat will only print the total duration as
// float
func TimeEntriesTotalDurationOnlyAsFloat(timeEntries []dto.TimeEntry, w io.Writer) error {
func TimeEntriesTotalDurationOnlyAsFloat(
timeEntries []dto.TimeEntry, w io.Writer,
l language.Tag) error {
p := message.NewPrinter(l)
println(l.String())

return timeEntriesTotalDurationOnly(
func(d time.Duration) string { return fmt.Sprintf("%f", d.Hours()) },
func(d time.Duration) string {
return p.Sprintf("%f", number.Decimal(d.Hours()))
},
timeEntries,
w,
)
Expand Down
51 changes: 51 additions & 0 deletions pkg/output/time-entry/duration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package timeentry_test

import (
"strings"
"testing"
"time"

"github.com/lucassabreu/clockify-cli/api/dto"
timeentry "github.com/lucassabreu/clockify-cli/pkg/output/time-entry"
"github.com/lucassabreu/clockify-cli/pkg/timehlp"
"github.com/stretchr/testify/assert"
"golang.org/x/text/language"
)

func TestTimeEntriesTotalDurationOnlyAsFloat_ShouldUseUserLanguage(
t *testing.T) {

start, _ := timehlp.ConvertToTime("2024-01-01 00:00")
end := start.Add(time.Hour*1000 + (time.Minute * 31))

tes := []dto.TimeEntry{
{TimeInterval: dto.NewTimeInterval(start, &end)},
}

tts := []struct {
name string
language language.Tag
output string
}{
{language: language.English, output: "1,000.517"},
{language: language.German, output: "1.000,517"},
{language: language.MustParse("pt-br"), output: "1.000,517"},
{language: language.Spanish, output: "1.000,517"},
{language: language.Afrikaans, output: "1\u00a0000,517"},
}

for _, tt := range tts {
t.Run(tt.language.String(), func(t *testing.T) {
buffer := strings.Builder{}

err := timeentry.TimeEntriesTotalDurationOnlyAsFloat(
tes, &buffer, tt.language)

if !assert.NoError(t, err) {
return
}

assert.Equal(t, tt.output+"\n", buffer.String())
})
}
}

0 comments on commit 66227eb

Please sign in to comment.