241 lines
6.0 KiB
Go

package pb
import (
"bytes"
"errors"
"fmt"
"strings"
"testing"
"time"
"github.com/fatih/color"
)
func TestPBBasic(t *testing.T) {
bar := new(ProgressBar)
var a, e int64
if a, e = bar.Total(), 0; a != e {
t.Errorf("Unexpected total: actual: %v; expected: %v", a, e)
}
if a, e = bar.Current(), 0; a != e {
t.Errorf("Unexpected current: actual: %v; expected: %v", a, e)
}
bar.SetCurrent(10).SetTotal(20)
if a, e = bar.Total(), 20; a != e {
t.Errorf("Unexpected total: actual: %v; expected: %v", a, e)
}
if a, e = bar.Current(), 10; a != e {
t.Errorf("Unexpected current: actual: %v; expected: %v", a, e)
}
bar.Add(5)
if a, e = bar.Current(), 15; a != e {
t.Errorf("Unexpected current: actual: %v; expected: %v", a, e)
}
bar.Increment()
if a, e = bar.Current(), 16; a != e {
t.Errorf("Unexpected current: actual: %v; expected: %v", a, e)
}
}
func TestPBWidth(t *testing.T) {
terminalWidth = func() (int, error) {
return 50, nil
}
// terminal width
bar := new(ProgressBar)
if a, e := bar.Width(), 50; a != e {
t.Errorf("Unexpected width: actual: %v; expected: %v", a, e)
}
// terminal width error
terminalWidth = func() (int, error) {
return 0, errors.New("test error")
}
if a, e := bar.Width(), defaultBarWidth; a != e {
t.Errorf("Unexpected width: actual: %v; expected: %v", a, e)
}
// terminal width panic
terminalWidth = func() (int, error) {
panic("test")
return 0, nil
}
if a, e := bar.Width(), defaultBarWidth; a != e {
t.Errorf("Unexpected width: actual: %v; expected: %v", a, e)
}
// set negative terminal width
bar.SetWidth(-42)
if a, e := bar.Width(), defaultBarWidth; a != e {
t.Errorf("Unexpected width: actual: %v; expected: %v", a, e)
}
// set terminal width
bar.SetWidth(42)
if a, e := bar.Width(), 42; a != e {
t.Errorf("Unexpected width: actual: %v; expected: %v", a, e)
}
}
func TestPBMaxWidth(t *testing.T) {
terminalWidth = func() (int, error) {
return 50, nil
}
// terminal width
bar := new(ProgressBar)
if a, e := bar.Width(), 50; a != e {
t.Errorf("Unexpected width: actual: %v; expected: %v", a, e)
}
bar.SetMaxWidth(55)
if a, e := bar.Width(), 50; a != e {
t.Errorf("Unexpected width: actual: %v; expected: %v", a, e)
}
bar.SetMaxWidth(38)
if a, e := bar.Width(), 38; a != e {
t.Errorf("Unexpected width: actual: %v; expected: %v", a, e)
}
}
func TestPBTemplate(t *testing.T) {
bar := new(ProgressBar)
result := bar.SetTotal(100).SetCurrent(50).SetWidth(40).String()
expected := "50 / 100 [------->________] 50.00% ? p/s"
if result != expected {
t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected)
}
// check strip
result = bar.SetWidth(8).String()
expected = "50 / 100"
if result != expected {
t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected)
}
// invalid template
for _, invalidTemplate := range []string{
`{{invalid template`, `{{speed}}`,
} {
bar.SetTemplateString(invalidTemplate)
result = bar.String()
expected = ""
if result != expected {
t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected)
}
if err := bar.Err(); err == nil {
t.Errorf("Must be error")
}
}
// simple template without adaptive elemnts
bar.SetTemplateString(`{{counters . }}`)
result = bar.String()
expected = "50 / 100"
if result != expected {
t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected)
}
}
func TestPBStartFinish(t *testing.T) {
bar := ProgressBarTemplate(`{{counters . }}`).New(0)
for i := int64(0); i < 2; i++ {
if bar.IsStarted() {
t.Error("Must be false")
}
var buf = bytes.NewBuffer(nil)
bar.SetTotal(100).
SetCurrent(int64(i)).
SetWidth(7).
Set(Terminal, true).
SetWriter(buf).
SetRefreshRate(time.Millisecond * 20).
Start()
if !bar.IsStarted() {
t.Error("Must be true")
}
time.Sleep(time.Millisecond * 100)
bar.Finish()
if buf.Len() == 0 {
t.Error("no writes")
}
var resultsString = strings.TrimPrefix(buf.String(), "\r")
if !strings.HasSuffix(resultsString, "\n") {
t.Error("No end \\n symb")
} else {
resultsString = resultsString[:len(resultsString)-1]
}
var results = strings.Split(resultsString, "\r")
if len(results) < 3 {
t.Errorf("Unexpected writes count: %v", len(results))
}
exp := fmt.Sprintf("%d / 100", i)
for i, res := range results {
if res != exp {
t.Errorf("Unexpected result[%d]: '%v'", i, res)
}
}
// test second finish call
bar.Finish()
}
}
func TestPBFlags(t *testing.T) {
// Static
color.NoColor = false
buf := bytes.NewBuffer(nil)
bar := ProgressBarTemplate(`{{counters . | red}}`).New(100)
bar.Set(Static, true).SetCurrent(50).SetWidth(10).SetWriter(buf).Start()
if bar.IsStarted() {
t.Error("Must be false")
}
bar.Write()
result := buf.String()
expected := "50 / 100"
if result != expected {
t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected)
}
if !bar.state.IsFirst() {
t.Error("must be true")
}
// Color
bar.Set(Color, true)
buf.Reset()
bar.Write()
result = buf.String()
expected = color.RedString("50 / 100")
if result != expected {
t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected)
}
if bar.state.IsFirst() {
t.Error("must be false")
}
// Terminal
bar.Set(Terminal, true).SetWriter(buf)
buf.Reset()
bar.Write()
result = buf.String()
expected = "\r" + color.RedString("50 / 100") + " "
if result != expected {
t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected)
}
}
func BenchmarkRender(b *testing.B) {
var formats = []string{
string(Simple),
string(Default),
string(Full),
`{{string . "prefix" | red}}{{counters . | green}} {{bar . | yellow}} {{percent . | cyan}} {{speed . | cyan}}{{string . "suffix" | cyan}}`,
}
var names = []string{
"Simple", "Default", "Full", "Color",
}
for i, tmpl := range formats {
bar := new(ProgressBar)
bar.SetTemplateString(tmpl).SetWidth(100)
b.Run(names[i], func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
bar.String()
}
})
}
}