From aef324ee24a66bf0825fdf0f900046749673e98d Mon Sep 17 00:00:00 2001 From: Denis Romanov Date: Sun, 13 Nov 2022 21:38:50 +0300 Subject: [PATCH] Add minor fix for full width mode --- progressbar.go | 25 +++++++-- progressbar_test.go | 121 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 5 deletions(-) diff --git a/progressbar.go b/progressbar.go index 044350f..2735483 100644 --- a/progressbar.go +++ b/progressbar.go @@ -634,7 +634,6 @@ func (p *ProgressBar) render() error { if !p.config.clearOnFinish { renderProgressBar(p.config, &p.state) } - if p.config.onCompletion != nil { p.config.onCompletion() } @@ -776,7 +775,7 @@ func renderProgressBar(c config, s *state) (int, error) { sb.WriteString(fmt.Sprintf("%0.0f %s/hr", 3600*averageRate, c.iterationString)) } } - if sb.Len() != 0 { + if sb.Len() > 0 { sb.WriteString(")") } @@ -804,7 +803,20 @@ func renderProgressBar(c config, s *state) (int, error) { } } - c.width = width - getStringWidth(c, c.description, true) - 14 - sb.Len() - len(leftBrac) - len(rightBrac) + amend := 1 // an extra space at eol + switch { + case leftBrac != "" && rightBrac != "": + amend = 4 // space, square brackets and colon + case leftBrac != "" && rightBrac == "": + amend = 4 // space and square brackets and another space + case leftBrac == "" && rightBrac != "": + amend = 3 // space and square brackets + } + if c.showDescriptionAtLineEnd { + amend += 1 // another space + } + + c.width = width - getStringWidth(c, c.description, true) - 10 - amend - sb.Len() - len(leftBrac) - len(rightBrac) s.currentSaucerSize = int(float64(s.currentPercent) / 100.0 * float64(c.width)) } if s.currentSaucerSize > 0 { @@ -882,10 +894,14 @@ func renderProgressBar(c config, s *state) (int, error) { c.theme.BarEnd, sb.String()) + if s.currentPercent == 100 && c.showElapsedTimeOnFinish { + str = fmt.Sprintf("%s [%s]", str, leftBrac) + } + if c.showDescriptionAtLineEnd { str = fmt.Sprintf("\r%s %s ", str, c.description) } else { - str = fmt.Sprintf("\r%s %s ", c.description, str) + str = fmt.Sprintf("\r%s%s ", c.description, str) } } else { if s.currentPercent == 100 { @@ -897,6 +913,7 @@ func renderProgressBar(c config, s *state) (int, error) { strings.Repeat(c.theme.SaucerPadding, repeatAmount), c.theme.BarEnd, sb.String()) + if c.showElapsedTimeOnFinish { str = fmt.Sprintf("%s [%s]", str, leftBrac) } diff --git a/progressbar_test.go b/progressbar_test.go index 790cf7f..0b6a90f 100644 --- a/progressbar_test.go +++ b/progressbar_test.go @@ -328,7 +328,6 @@ func TestBasicSets(t *testing.T) { 999, OptionSetWidth(888), OptionSetRenderBlankState(true), - OptionSetWriter(io.Discard), // suppressing output for this test ) @@ -656,3 +655,123 @@ func TestRenderBlankStateWithThrottle(t *testing.T) { t.Errorf("Render miss-match\nResult: '%s'\nExpect: '%s'\n%+v", result, expect, bar) } } + +func TestOptionFullWidth(t *testing.T) { + var tests = []struct { + opts []Option + expected string + }{ + { // 1 + []Option{}, + "" + + "\r 10% |██████ | [1s:9s]" + + "\r \r" + + "\r 100% |██████████████████████████████████████████████████████████████| ", + }, + { // 2 + []Option{OptionSetDescription("Progress:")}, + "" + + "\rProgress: 10% |█████ | [1s:9s]" + + "\r \r" + + "\rProgress: 100% |█████████████████████████████████████████████████████| ", + }, + { // 3 + []Option{OptionSetDescription("<1/5>"), OptionShowDescriptionAtLineEnd()}, + "" + + "\r 10% |█████ | [1s:9s] <1/5>" + + "\r \r" + + "\r 100% |████████████████████████████████████████████████████████| <1/5>", + }, + { // 4 + []Option{OptionSetPredictTime(false)}, + "" + + "\r 10% |██████ | " + + "\r \r" + + "\r 100% |████████████████████████████████████████████████████████████████| ", + }, + { // 5 + []Option{OptionSetPredictTime(false), OptionShowElapsedTimeOnFinish()}, + "" + + "\r 10% |██████ | " + + "\r \r" + + "\r 100% |████████████████████████████████████████████████████████████████| [2s] ", + }, + { // 6 + []Option{OptionSetPredictTime(false), OptionSetElapsedTime(false)}, + "" + + "\r 10% |██████ | " + + "\r \r" + + "\r 100% |█████████████████████████████████████████████████████████████████████| ", + }, + { // 7 + []Option{OptionShowIts()}, + "" + + "\r 10% |█████ | (10 it/s) [1s:9s]" + + "\r \r" + + "\r 100% |█████████████████████████████████████████████████████| (50 it/s)", + }, + { // 8 + []Option{OptionShowCount()}, + "" + + "\r 10% |█████ | (10/100) [1s:9s]" + + "\r \r" + + "\r 100% |█████████████████████████████████████████████████████| (100/100)", + }, + { // 9 + []Option{OptionShowIts(), OptionShowCount(), OptionShowElapsedTimeOnFinish()}, + "" + + "\r 10% |████ | (10/100, 10 it/s) [1s:9s]" + + "\r \r" + + "\r 100% |████████████████████████████████████████████| (100/100, 50 it/s) [2s]", + }, + { // 10 + []Option{OptionSetDescription("Progress:"), OptionShowIts(), OptionShowCount()}, + "" + + "\rProgress: 10% |███ | (10/100, 10 it/s) [1s:9s]" + + "\r \r" + + "\rProgress: 100% |███████████████████████████████████| (100/100, 50 it/s)", + }, + { // 11 + []Option{OptionSetDescription("<3/5>"), OptionShowIts(), OptionShowCount(), OptionShowElapsedTimeOnFinish(), OptionShowDescriptionAtLineEnd()}, + "" + + "\r 10% |███ | (10/100, 10 it/s) [1s:9s] <3/5>" + + "\r \r" + + "\r 100% |██████████████████████████████████████| (100/100, 50 it/s) [2s] <3/5>", + }, + { // 12 + []Option{OptionShowIts(), OptionShowCount(), OptionSetPredictTime(false)}, + "" + + "\r 10% |████ | (10/100, 10 it/s) " + + "\r \r" + + "\r 100% |██████████████████████████████████████████████| (100/100, 50 it/s) ", + }, + { // 13 + []Option{OptionShowIts(), OptionShowCount(), OptionSetPredictTime(false), OptionShowElapsedTimeOnFinish()}, + "" + + "\r 10% |████ | (10/100, 10 it/s) " + + "\r \r" + + "\r 100% |██████████████████████████████████████████████| (100/100, 50 it/s) [2s] ", + }, + { // 14 + []Option{OptionShowIts(), OptionShowCount(), OptionSetPredictTime(false), OptionSetElapsedTime(false)}, + "" + + "\r 10% |█████ | (10/100, 10 it/s) " + + "\r \r" + + "\r 100% |███████████████████████████████████████████████████| (100/100, 50 it/s) ", + }, + } + + for i, test := range tests { + test := test + t.Run(fmt.Sprintf("%d", i+1), func(t *testing.T) { + t.Parallel() + buf := strings.Builder{} + bar := NewOptions(100, append(test.opts, []Option{OptionFullWidth(), OptionSetWriter(&buf)}...)...) + time.Sleep(1 * time.Second) + bar.Add(10) + time.Sleep(1 * time.Second) + bar.Add(90) + assert.Equal(t, test.expected, buf.String()) + }) + } +}