diff --git a/decor/decorators.go b/decor/decorators.go index d442e55..e66108b 100644 --- a/decor/decorators.go +++ b/decor/decorators.go @@ -204,10 +204,14 @@ } } -func CalcPercentage(total, current, width int64) int64 { - if total == 0 || current > total { +func CalcPercentage(total, current, width int64) (perc int64) { + if total <= 0 { return 0 } + if current > total { + current = total + } + num := float64(width) * float64(current) / float64(total) ceil := math.Ceil(num) diff := ceil - num diff --git a/decor/percentage_test.go b/decor/percentage_test.go new file mode 100644 index 0000000..e0672bb --- /dev/null +++ b/decor/percentage_test.go @@ -0,0 +1,68 @@ +package decor + +import "testing" + +func TestCalcPersentage(t *testing.T) { + // key is barWidth + testSuite := map[int64]map[string]struct { + total, current, expected int64 + }{ + 100: { + "t,c,e{-1,-1,0}": {-1, -1, 0}, + "t,c,e{0,-1,0}": {0, -1, 0}, + "t,c,e{0,0,0}": {0, 0, 0}, + "t,c,e{0,1,0}": {0, 1, 0}, + "t,c,e{100,0,0}": {100, 0, 0}, + "t,c,e{100,10,10}": {100, 10, 10}, + "t,c,e{100,15,15}": {100, 15, 15}, + "t,c,e{100,50,50}": {100, 50, 50}, + "t,c,e{100,99,99}": {100, 99, 99}, + "t,c,e{100,100,100}": {100, 100, 100}, + "t,c,e{100,101,100}": {100, 101, 100}, + "t,c,e{120,0,0}": {120, 0, 0}, + "t,c,e{120,10,8}": {120, 10, 8}, + "t,c,e{120,15,13}": {120, 15, 13}, + "t,c,e{120,50,42}": {120, 50, 42}, + "t,c,e{120,60,50}": {120, 60, 50}, + "t,c,e{120,99,83}": {120, 99, 83}, + "t,c,e{120,101,84}": {120, 101, 84}, + "t,c,e{120,118,98}": {120, 118, 98}, + "t,c,e{120,119,99}": {120, 119, 99}, + "t,c,e{120,120,100}": {120, 120, 100}, + "t,c,e{120,121,100}": {120, 121, 100}, + }, + 80: { + "t,c,e{-1,-1,0}": {-1, -1, 0}, + "t,c,e{0,-1,0}": {0, -1, 0}, + "t,c,e{0,0,0}": {0, 0, 0}, + "t,c,e{0,1,0}": {0, 1, 0}, + "t,c,e{100,0,0}": {100, 0, 0}, + "t,c,e{100,10,8}": {100, 10, 8}, + "t,c,e{100,15,12}": {100, 15, 12}, + "t,c,e{100,50,40}": {100, 50, 40}, + "t,c,e{100,99,79}": {100, 99, 79}, + "t,c,e{100,100,80}": {100, 100, 80}, + "t,c,e{100,101,80}": {100, 101, 80}, + "t,c,e{120,0,0}": {120, 0, 0}, + "t,c,e{120,10,7}": {120, 10, 7}, + "t,c,e{120,15,10}": {120, 15, 10}, + "t,c,e{120,50,33}": {120, 50, 33}, + "t,c,e{120,60,40}": {120, 60, 40}, + "t,c,e{120,99,66}": {120, 99, 66}, + "t,c,e{120,101,67}": {120, 101, 67}, + "t,c,e{120,118,79}": {120, 118, 79}, + "t,c,e{120,119,79}": {120, 119, 79}, + "t,c,e{120,120,80}": {120, 120, 80}, + "t,c,e{120,121,80}": {120, 121, 80}, + }, + } + + for width, cases := range testSuite { + for name, tc := range cases { + got := CalcPercentage(tc.total, tc.current, width) + if got != tc.expected { + t.Errorf("width %d; %s: Expected: %d, got: %d\n", width, name, tc.expected, got) + } + } + } +} diff --git a/draw_test.go b/draw_test.go index 7bd6967..c056fcf 100644 --- a/draw_test.go +++ b/draw_test.go @@ -6,113 +6,194 @@ ) func TestFillBar(t *testing.T) { - tests := []struct { - termWidth int - barWidth int - total int64 - current int64 - barRefill *refill - want string + // key is termWidth + testSuite := map[int]map[string]struct { + total, current int64 + barWidth int + barRefill *refill + want string }{ - { - termWidth: 2, - barWidth: 100, - want: "[]", - }, - { - termWidth: 3, - barWidth: 100, - total: 100, - current: 20, - want: "[-]", - }, - { - termWidth: 5, - barWidth: 100, - total: 100, - current: 20, - want: "[>--]", - }, - { - termWidth: 6, - barWidth: 100, - total: 100, - current: 20, - want: "[>---]", - }, - { - termWidth: 20, - barWidth: 100, - total: 100, - current: 20, - want: "[===>--------------]", - }, - { - termWidth: 50, - barWidth: 100, - total: 100, - current: 20, - want: "[=========>--------------------------------------]", - }, - { - termWidth: 100, - barWidth: 100, - total: 100, - current: 0, - want: "[--------------------------------------------------------------------------------------------------]", - }, - { - termWidth: 100, - barWidth: 100, - total: 100, - current: 1, - want: "[>-------------------------------------------------------------------------------------------------]", - }, - { - termWidth: 100, - barWidth: 100, - total: 100, - current: 40, - want: "[======================================>-----------------------------------------------------------]", - }, - { - termWidth: 100, - barWidth: 100, - total: 100, - current: 40, - barRefill: &refill{'+', 32}, - want: "[+++++++++++++++++++++++++++++++=======>-----------------------------------------------------------]", - }, - { - termWidth: 100, - barWidth: 100, - total: 100, - current: 99, - want: "[================================================================================================>-]", - }, - { - termWidth: 100, - barWidth: 100, - total: 100, - current: 100, - want: "[==================================================================================================]", + 100: { + "t,c,bw{100,100,0}": { + total: 100, + current: 0, + barWidth: 100, + want: "[--------------------------------------------------------------------------------------------------]", + }, + "t,c,bw{100,1,100}": { + total: 100, + current: 1, + barWidth: 100, + want: "[>-------------------------------------------------------------------------------------------------]", + }, + "t,c,bw{100,40,100}": { + total: 100, + current: 40, + barWidth: 100, + want: "[======================================>-----------------------------------------------------------]", + }, + "t,c,bw{100,40,100}refill{'+', 32}": { + total: 100, + current: 40, + barWidth: 100, + barRefill: &refill{'+', 32}, + want: "[+++++++++++++++++++++++++++++++=======>-----------------------------------------------------------]", + }, + "t,c,bw{100,99,100}": { + total: 100, + current: 99, + barWidth: 100, + want: "[================================================================================================>-]", + }, + "t,c,bw{100,100,100}": { + total: 100, + current: 100, + barWidth: 100, + want: "[==================================================================================================]", + }, + }, + 2: { + "t,c,bw{0,0,100}": { + barWidth: 100, + want: "[]", + }, + "t,c,bw{60,20,80}": { + total: 60, + current: 20, + barWidth: 80, + want: "[]", + }, + }, + 3: { + "t,c,bw{100,20,100}": { + total: 100, + current: 20, + barWidth: 100, + want: "[-]", + }, + "t,c,bw{100,98,100}": { + total: 100, + current: 98, + barWidth: 100, + want: "[=]", + }, + "t,c,bw{100,100,100}": { + total: 100, + current: 100, + barWidth: 100, + want: "[=]", + }, + }, + 5: { + "t,c,bw{100,20,100}": { + total: 100, + current: 20, + barWidth: 100, + want: "[>--]", + }, + "t,c,bw{100,98,100}": { + total: 100, + current: 98, + barWidth: 100, + want: "[===]", + }, + "t,c,bw{100,100,100}": { + total: 100, + current: 100, + barWidth: 100, + want: "[===]", + }, + }, + 6: { + "t,c,bw{100,20,100}": { + total: 100, + current: 20, + barWidth: 100, + want: "[>---]", + }, + "t,c,bw{100,98,100}": { + total: 100, + current: 98, + barWidth: 100, + want: "[====]", + }, + "t,c,bw{100,100,100}": { + total: 100, + current: 100, + barWidth: 100, + want: "[====]", + }, + }, + 20: { + "t,c,bw{100,20,100}": { + total: 100, + current: 20, + barWidth: 100, + want: "[===>--------------]", + }, + "t,c,bw{100,60,100}": { + total: 100, + current: 60, + barWidth: 100, + want: "[==========>-------]", + }, + "t,c,bw{100,98,100}": { + total: 100, + current: 98, + barWidth: 100, + want: "[==================]", + }, + "t,c,bw{100,100,100}": { + total: 100, + current: 100, + barWidth: 100, + want: "[==================]", + }, + }, + 50: { + "t,c,bw{100,20,100}": { + total: 100, + current: 20, + barWidth: 100, + want: "[=========>--------------------------------------]", + }, + "t,c,bw{100,60,100}": { + total: 100, + current: 60, + barWidth: 100, + want: "[============================>-------------------]", + }, + "t,c,bw{100,98,100}": { + total: 100, + current: 98, + barWidth: 100, + want: "[==============================================>-]", + }, + "t,c,bw{100,100,100}": { + total: 100, + current: 100, + barWidth: 100, + want: "[================================================]", + }, }, } prependWs := newWidthSync(nil, 1, 0) appendWs := newWidthSync(nil, 1, 0) - for _, test := range tests { - s := newTestState() - s.width = test.barWidth - s.total = test.total - s.current = test.current - if test.barRefill != nil { - s.refill = test.barRefill - } - s.draw(test.termWidth, prependWs, appendWs) - got := s.bufB.String() - if got != test.want { - t.Errorf("Want: %q, Got: %q\n", test.want, got) + for termWidth, cases := range testSuite { + for name, tc := range cases { + s := newTestState() + s.width = tc.barWidth + s.total = tc.total + s.current = tc.current + if tc.barRefill != nil { + s.refill = tc.barRefill + } + s.draw(termWidth, prependWs, appendWs) + got := s.bufB.String() + if got != tc.want { + t.Errorf("termWidth %d; %s: want: %s %d, got: %s %d\n", termWidth, name, tc.want, len(tc.want), got, len(got)) + } } } }