generate size types
Vladimir Bauer
6 years ago
| 1 | 1 | |
| 2 | 2 | import ( |
| 3 | 3 | "fmt" |
| 4 | "io" | |
| 5 | "strconv" | |
| 6 | "strings" | |
| 7 | ) | |
| 8 | ||
| 9 | const ( | |
| 10 | _ = iota | |
| 11 | KiB = 1 << (iota * 10) | |
| 12 | MiB | |
| 13 | GiB | |
| 14 | TiB | |
| 15 | ) | |
| 16 | ||
| 17 | const ( | |
| 18 | KB = 1000 | |
| 19 | MB = KB * 1000 | |
| 20 | GB = MB * 1000 | |
| 21 | TB = GB * 1000 | |
| 22 | 4 | ) |
| 23 | 5 | |
| 24 | 6 | const ( |
| 26 | 8 | UnitKiB |
| 27 | 9 | UnitKB |
| 28 | 10 | ) |
| 29 | ||
| 30 | type CounterKiB int64 | |
| 31 | ||
| 32 | func (c CounterKiB) Format(st fmt.State, verb rune) { | |
| 33 | var prec int | |
| 34 | switch verb { | |
| 35 | case 'd': | |
| 36 | case 's': | |
| 37 | prec = -1 | |
| 38 | default: | |
| 39 | if p, ok := st.Precision(); ok { | |
| 40 | prec = p | |
| 41 | } else { | |
| 42 | prec = 6 | |
| 43 | } | |
| 44 | } | |
| 45 | ||
| 46 | var res, unit string | |
| 47 | switch { | |
| 48 | case c >= TiB: | |
| 49 | unit = "TiB" | |
| 50 | res = strconv.FormatFloat(float64(c)/TiB, 'f', prec, 64) | |
| 51 | case c >= GiB: | |
| 52 | unit = "GiB" | |
| 53 | res = strconv.FormatFloat(float64(c)/GiB, 'f', prec, 64) | |
| 54 | case c >= MiB: | |
| 55 | unit = "MiB" | |
| 56 | res = strconv.FormatFloat(float64(c)/MiB, 'f', prec, 64) | |
| 57 | case c >= KiB: | |
| 58 | unit = "KiB" | |
| 59 | res = strconv.FormatFloat(float64(c)/KiB, 'f', prec, 64) | |
| 60 | default: | |
| 61 | unit = "b" | |
| 62 | res = strconv.FormatInt(int64(c), 10) | |
| 63 | } | |
| 64 | ||
| 65 | if st.Flag(' ') { | |
| 66 | res += " " | |
| 67 | } | |
| 68 | res += unit | |
| 69 | ||
| 70 | if w, ok := st.Width(); ok { | |
| 71 | if len(res) < w { | |
| 72 | pad := strings.Repeat(" ", w-len(res)) | |
| 73 | if st.Flag('-') { | |
| 74 | res += pad | |
| 75 | } else { | |
| 76 | res = pad + res | |
| 77 | } | |
| 78 | } | |
| 79 | } | |
| 80 | ||
| 81 | io.WriteString(st, res) | |
| 82 | } | |
| 83 | ||
| 84 | type CounterKB int64 | |
| 85 | ||
| 86 | func (c CounterKB) Format(st fmt.State, verb rune) { | |
| 87 | var prec int | |
| 88 | switch verb { | |
| 89 | case 'd': | |
| 90 | case 's': | |
| 91 | prec = -1 | |
| 92 | default: | |
| 93 | if p, ok := st.Precision(); ok { | |
| 94 | prec = p | |
| 95 | } else { | |
| 96 | prec = 6 | |
| 97 | } | |
| 98 | } | |
| 99 | ||
| 100 | var res, unit string | |
| 101 | switch { | |
| 102 | case c >= TB: | |
| 103 | unit = "TB" | |
| 104 | res = strconv.FormatFloat(float64(c)/TB, 'f', prec, 64) | |
| 105 | case c >= GB: | |
| 106 | unit = "GB" | |
| 107 | res = strconv.FormatFloat(float64(c)/GB, 'f', prec, 64) | |
| 108 | case c >= MB: | |
| 109 | unit = "MB" | |
| 110 | res = strconv.FormatFloat(float64(c)/MB, 'f', prec, 64) | |
| 111 | case c >= KB: | |
| 112 | unit = "kB" | |
| 113 | res = strconv.FormatFloat(float64(c)/KB, 'f', prec, 64) | |
| 114 | default: | |
| 115 | unit = "b" | |
| 116 | res = strconv.FormatInt(int64(c), 10) | |
| 117 | } | |
| 118 | ||
| 119 | if st.Flag(' ') { | |
| 120 | res += " " | |
| 121 | } | |
| 122 | res += unit | |
| 123 | ||
| 124 | if w, ok := st.Width(); ok { | |
| 125 | if len(res) < w { | |
| 126 | pad := strings.Repeat(" ", w-len(res)) | |
| 127 | if st.Flag('-') { | |
| 128 | res += pad | |
| 129 | } else { | |
| 130 | res = pad + res | |
| 131 | } | |
| 132 | } | |
| 133 | } | |
| 134 | ||
| 135 | io.WriteString(st, res) | |
| 136 | } | |
| 137 | 11 | |
| 138 | 12 | // CountersNoUnit is a wrapper around Counters with no unit param. |
| 139 | 13 | func CountersNoUnit(pairFmt string, wcc ...WC) Decorator { |
| 190 | 64 | return d.FormatMsg(*d.completeMsg) |
| 191 | 65 | } |
| 192 | 66 | |
| 193 | var str string | |
| 67 | var res string | |
| 194 | 68 | switch d.unit { |
| 195 | 69 | case UnitKiB: |
| 196 | str = fmt.Sprintf(d.pairFmt, CounterKiB(st.Current), CounterKiB(st.Total)) | |
| 70 | res = fmt.Sprintf(d.pairFmt, SizeB1024(st.Current), SizeB1024(st.Total)) | |
| 197 | 71 | case UnitKB: |
| 198 | str = fmt.Sprintf(d.pairFmt, CounterKB(st.Current), CounterKB(st.Total)) | |
| 72 | res = fmt.Sprintf(d.pairFmt, SizeB1000(st.Current), SizeB1000(st.Total)) | |
| 199 | 73 | default: |
| 200 | str = fmt.Sprintf(d.pairFmt, st.Current, st.Total) | |
| 74 | res = fmt.Sprintf(d.pairFmt, st.Current, st.Total) | |
| 201 | 75 | } |
| 202 | 76 | |
| 203 | return d.FormatMsg(str) | |
| 77 | return d.FormatMsg(res) | |
| 204 | 78 | } |
| 205 | 79 | |
| 206 | 80 | func (d *countersDecorator) OnCompleteMessage(msg string) { |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "testing" | |
| 5 | ) | |
| 6 | ||
| 7 | func TestCounterKiB(t *testing.T) { | |
| 8 | cases := map[string]struct { | |
| 9 | value int64 | |
| 10 | verb string | |
| 11 | expected string | |
| 12 | }{ | |
| 13 | "verb %f": {12345678, "%f", "11.773756MiB"}, | |
| 14 | "verb %.0f": {12345678, "%.0f", "12MiB"}, | |
| 15 | "verb %.1f": {12345678, "%.1f", "11.8MiB"}, | |
| 16 | "verb %.2f": {12345678, "%.2f", "11.77MiB"}, | |
| 17 | "verb %.3f": {12345678, "%.3f", "11.774MiB"}, | |
| 18 | ||
| 19 | "verb % f": {12345678, "% f", "11.773756 MiB"}, | |
| 20 | "verb % .0f": {12345678, "% .0f", "12 MiB"}, | |
| 21 | "verb % .1f": {12345678, "% .1f", "11.8 MiB"}, | |
| 22 | "verb % .2f": {12345678, "% .2f", "11.77 MiB"}, | |
| 23 | "verb % .3f": {12345678, "% .3f", "11.774 MiB"}, | |
| 24 | ||
| 25 | "verb %8.f": {12345678, "%8.f", " 12MiB"}, | |
| 26 | "verb %8.0f": {12345678, "%8.0f", " 12MiB"}, | |
| 27 | "verb %8.1f": {12345678, "%8.1f", " 11.8MiB"}, | |
| 28 | "verb %8.2f": {12345678, "%8.2f", "11.77MiB"}, | |
| 29 | "verb %8.3f": {12345678, "%8.3f", "11.774MiB"}, | |
| 30 | ||
| 31 | "verb % 8.f": {12345678, "% 8.f", " 12 MiB"}, | |
| 32 | "verb % 8.0f": {12345678, "% 8.0f", " 12 MiB"}, | |
| 33 | "verb % 8.1f": {12345678, "% 8.1f", "11.8 MiB"}, | |
| 34 | ||
| 35 | "verb %-8.f": {12345678, "%-8.f", "12MiB "}, | |
| 36 | "verb %-8.0f": {12345678, "%-8.0f", "12MiB "}, | |
| 37 | "verb %-8.1f": {12345678, "%-8.1f", "11.8MiB "}, | |
| 38 | "verb %-8.2f": {12345678, "%8.2f", "11.77MiB"}, | |
| 39 | "verb %-8.3f": {12345678, "%8.3f", "11.774MiB"}, | |
| 40 | ||
| 41 | "verb % -8.f": {12345678, "% -8.f", "12 MiB "}, | |
| 42 | "verb % -8.0f": {12345678, "% -8.0f", "12 MiB "}, | |
| 43 | "verb % -8.1f": {12345678, "% -8.1f", "11.8 MiB"}, | |
| 44 | ||
| 45 | "1000 %f": {1000, "%f", "1000b"}, | |
| 46 | "1000 %d": {1000, "%d", "1000b"}, | |
| 47 | "1000 %s": {1000, "%s", "1000b"}, | |
| 48 | "1024 %f": {1024, "%f", "1.000000KiB"}, | |
| 49 | "1024 %d": {1024, "%d", "1KiB"}, | |
| 50 | "1024 %.1f": {1024, "%.1f", "1.0KiB"}, | |
| 51 | "1024 %s": {1024, "%s", "1KiB"}, | |
| 52 | "3*MiB+140KiB %f": {3*MiB + 140*KiB, "%f", "3.136719MiB"}, | |
| 53 | "3*MiB+140KiB %d": {3*MiB + 140*KiB, "%d", "3MiB"}, | |
| 54 | "3*MiB+140KiB %.1f": {3*MiB + 140*KiB, "%.1f", "3.1MiB"}, | |
| 55 | "3*MiB+140KiB %s": {3*MiB + 140*KiB, "%s", "3.13671875MiB"}, | |
| 56 | "2*GiB %f": {2 * GiB, "%f", "2.000000GiB"}, | |
| 57 | "2*GiB %d": {2 * GiB, "%d", "2GiB"}, | |
| 58 | "2*GiB %.1f": {2 * GiB, "%.1f", "2.0GiB"}, | |
| 59 | "2*GiB %s": {2 * GiB, "%s", "2GiB"}, | |
| 60 | "4*TiB %f": {4 * TiB, "%f", "4.000000TiB"}, | |
| 61 | "4*TiB %d": {4 * TiB, "%d", "4TiB"}, | |
| 62 | "4*TiB %.1f": {4 * TiB, "%.1f", "4.0TiB"}, | |
| 63 | "4*TiB %s": {4 * TiB, "%s", "4TiB"}, | |
| 64 | } | |
| 65 | for name, tc := range cases { | |
| 66 | t.Run(name, func(t *testing.T) { | |
| 67 | got := fmt.Sprintf(tc.verb, CounterKiB(tc.value)) | |
| 68 | if got != tc.expected { | |
| 69 | t.Fatalf("expected: %q, got: %q\n", tc.expected, got) | |
| 70 | } | |
| 71 | }) | |
| 72 | } | |
| 73 | } | |
| 74 | ||
| 75 | func TestCounterKB(t *testing.T) { | |
| 76 | cases := map[string]struct { | |
| 77 | value int64 | |
| 78 | verb string | |
| 79 | expected string | |
| 80 | }{ | |
| 81 | "verb %f": {12345678, "%f", "12.345678MB"}, | |
| 82 | "verb %.0f": {12345678, "%.0f", "12MB"}, | |
| 83 | "verb %.1f": {12345678, "%.1f", "12.3MB"}, | |
| 84 | "verb %.2f": {12345678, "%.2f", "12.35MB"}, | |
| 85 | "verb %.3f": {12345678, "%.3f", "12.346MB"}, | |
| 86 | ||
| 87 | "verb % f": {12345678, "% f", "12.345678 MB"}, | |
| 88 | "verb % .0f": {12345678, "% .0f", "12 MB"}, | |
| 89 | "verb % .1f": {12345678, "% .1f", "12.3 MB"}, | |
| 90 | "verb % .2f": {12345678, "% .2f", "12.35 MB"}, | |
| 91 | "verb % .3f": {12345678, "% .3f", "12.346 MB"}, | |
| 92 | ||
| 93 | "verb %8.f": {12345678, "%8.f", " 12MB"}, | |
| 94 | "verb %8.0f": {12345678, "%8.0f", " 12MB"}, | |
| 95 | "verb %8.1f": {12345678, "%8.1f", " 12.3MB"}, | |
| 96 | "verb %8.2f": {12345678, "%8.2f", " 12.35MB"}, | |
| 97 | "verb %8.3f": {12345678, "%8.3f", "12.346MB"}, | |
| 98 | ||
| 99 | "verb % 8.f": {12345678, "% 8.f", " 12 MB"}, | |
| 100 | "verb % 8.0f": {12345678, "% 8.0f", " 12 MB"}, | |
| 101 | "verb % 8.1f": {12345678, "% 8.1f", " 12.3 MB"}, | |
| 102 | ||
| 103 | "verb %-8.f": {12345678, "%-8.f", "12MB "}, | |
| 104 | "verb %-8.0f": {12345678, "%-8.0f", "12MB "}, | |
| 105 | "verb %-8.1f": {12345678, "%-8.1f", "12.3MB "}, | |
| 106 | "verb %-8.2f": {12345678, "%8.2f", " 12.35MB"}, | |
| 107 | "verb %-8.3f": {12345678, "%8.3f", "12.346MB"}, | |
| 108 | ||
| 109 | "verb % -8.f": {12345678, "% -8.f", "12 MB "}, | |
| 110 | "verb % -8.0f": {12345678, "% -8.0f", "12 MB "}, | |
| 111 | "verb % -8.1f": {12345678, "% -8.1f", "12.3 MB "}, | |
| 112 | ||
| 113 | "1000 %f": {1000, "%f", "1.000000kB"}, | |
| 114 | "1000 %d": {1000, "%d", "1kB"}, | |
| 115 | "1000 %s": {1000, "%s", "1kB"}, | |
| 116 | "1024 %f": {1024, "%f", "1.024000kB"}, | |
| 117 | "1024 %d": {1024, "%d", "1kB"}, | |
| 118 | "1024 %.1f": {1024, "%.1f", "1.0kB"}, | |
| 119 | "1024 %s": {1024, "%s", "1.024kB"}, | |
| 120 | "3*MB+140*KB %f": {3*MB + 140*KB, "%f", "3.140000MB"}, | |
| 121 | "3*MB+140*KB %d": {3*MB + 140*KB, "%d", "3MB"}, | |
| 122 | "3*MB+140*KB %.1f": {3*MB + 140*KB, "%.1f", "3.1MB"}, | |
| 123 | "3*MB+140*KB %s": {3*MB + 140*KB, "%s", "3.14MB"}, | |
| 124 | "2*GB %f": {2 * GB, "%f", "2.000000GB"}, | |
| 125 | "2*GB %d": {2 * GB, "%d", "2GB"}, | |
| 126 | "2*GB %.1f": {2 * GB, "%.1f", "2.0GB"}, | |
| 127 | "2*GB %s": {2 * GB, "%s", "2GB"}, | |
| 128 | "4*TB %f": {4 * TB, "%f", "4.000000TB"}, | |
| 129 | "4*TB %d": {4 * TB, "%d", "4TB"}, | |
| 130 | "4*TB %.1f": {4 * TB, "%.1f", "4.0TB"}, | |
| 131 | "4*TB %s": {4 * TB, "%s", "4TB"}, | |
| 132 | } | |
| 133 | for name, tc := range cases { | |
| 134 | t.Run(name, func(t *testing.T) { | |
| 135 | got := fmt.Sprintf(tc.verb, CounterKB(tc.value)) | |
| 136 | if got != tc.expected { | |
| 137 | t.Fatalf("expected: %q, got: %q\n", tc.expected, got) | |
| 138 | } | |
| 139 | }) | |
| 140 | } | |
| 141 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "io" | |
| 5 | "math" | |
| 6 | "strconv" | |
| 7 | "strings" | |
| 8 | ) | |
| 9 | ||
| 10 | const ( | |
| 11 | _ib SizeB1024 = iota | |
| 12 | _iKiB SizeB1024 = 1 << (iota * 10) | |
| 13 | _iMiB | |
| 14 | _iGiB | |
| 15 | _iTiB | |
| 16 | ) | |
| 17 | ||
| 18 | //go:generate stringer -type=SizeB1024 -trimprefix=_i | |
| 19 | type SizeB1024 int64 | |
| 20 | ||
| 21 | func (self SizeB1024) Format(st fmt.State, verb rune) { | |
| 22 | var prec int | |
| 23 | switch verb { | |
| 24 | case 'd': | |
| 25 | case 's': | |
| 26 | prec = -1 | |
| 27 | default: | |
| 28 | if p, ok := st.Precision(); ok { | |
| 29 | prec = p | |
| 30 | } else { | |
| 31 | prec = 6 | |
| 32 | } | |
| 33 | } | |
| 34 | ||
| 35 | var b strings.Builder | |
| 36 | var unit SizeB1024 | |
| 37 | switch { | |
| 38 | case self < _iKiB: | |
| 39 | unit = _ib | |
| 40 | b.WriteString(strconv.FormatFloat(float64(self), 'f', prec, 64)) | |
| 41 | case self < _iMiB: | |
| 42 | unit = _iKiB | |
| 43 | b.WriteString(strconv.FormatFloat(float64(self)/float64(_iKiB), 'f', prec, 64)) | |
| 44 | case self < _iGiB: | |
| 45 | unit = _iMiB | |
| 46 | b.WriteString(strconv.FormatFloat(float64(self)/float64(_iMiB), 'f', prec, 64)) | |
| 47 | case self < _iTiB: | |
| 48 | unit = _iGiB | |
| 49 | b.WriteString(strconv.FormatFloat(float64(self)/float64(_iGiB), 'f', prec, 64)) | |
| 50 | case self <= math.MaxInt64: | |
| 51 | unit = _iTiB | |
| 52 | b.WriteString(strconv.FormatFloat(float64(self)/float64(_iTiB), 'f', prec, 64)) | |
| 53 | } | |
| 54 | ||
| 55 | if st.Flag(' ') { | |
| 56 | b.WriteString(" ") | |
| 57 | } | |
| 58 | b.WriteString(unit.String()) | |
| 59 | ||
| 60 | if w, ok := st.Width(); ok { | |
| 61 | if l := b.Len(); l < w { | |
| 62 | pad := strings.Repeat(" ", w-l) | |
| 63 | if st.Flag('-') { | |
| 64 | b.WriteString(pad) | |
| 65 | } else { | |
| 66 | tmp := b.String() | |
| 67 | b.Reset() | |
| 68 | b.WriteString(pad) | |
| 69 | b.WriteString(tmp) | |
| 70 | } | |
| 71 | } | |
| 72 | } | |
| 73 | ||
| 74 | io.WriteString(st, b.String()) | |
| 75 | } | |
| 76 | ||
| 77 | const ( | |
| 78 | _b SizeB1000 = 0 | |
| 79 | _KB SizeB1000 = 1000 | |
| 80 | _MB SizeB1000 = _KB * 1000 | |
| 81 | _GB SizeB1000 = _MB * 1000 | |
| 82 | _TB SizeB1000 = _GB * 1000 | |
| 83 | ) | |
| 84 | ||
| 85 | //go:generate stringer -type=SizeB1000 -trimprefix=_ | |
| 86 | type SizeB1000 int64 | |
| 87 | ||
| 88 | func (self SizeB1000) Format(st fmt.State, verb rune) { | |
| 89 | var prec int | |
| 90 | switch verb { | |
| 91 | case 'd': | |
| 92 | case 's': | |
| 93 | prec = -1 | |
| 94 | default: | |
| 95 | if p, ok := st.Precision(); ok { | |
| 96 | prec = p | |
| 97 | } else { | |
| 98 | prec = 6 | |
| 99 | } | |
| 100 | } | |
| 101 | ||
| 102 | var b strings.Builder | |
| 103 | var unit SizeB1000 | |
| 104 | switch { | |
| 105 | case self < _KB: | |
| 106 | unit = _b | |
| 107 | b.WriteString(strconv.FormatFloat(float64(self), 'f', prec, 64)) | |
| 108 | case self < _MB: | |
| 109 | unit = _KB | |
| 110 | b.WriteString(strconv.FormatFloat(float64(self)/float64(_KB), 'f', prec, 64)) | |
| 111 | case self < _GB: | |
| 112 | unit = _MB | |
| 113 | b.WriteString(strconv.FormatFloat(float64(self)/float64(_MB), 'f', prec, 64)) | |
| 114 | case self < _TB: | |
| 115 | unit = _GB | |
| 116 | b.WriteString(strconv.FormatFloat(float64(self)/float64(_GB), 'f', prec, 64)) | |
| 117 | case self <= math.MaxInt64: | |
| 118 | unit = _TB | |
| 119 | b.WriteString(strconv.FormatFloat(float64(self)/float64(_TB), 'f', prec, 64)) | |
| 120 | } | |
| 121 | ||
| 122 | if st.Flag(' ') { | |
| 123 | b.WriteString(" ") | |
| 124 | } | |
| 125 | b.WriteString(unit.String()) | |
| 126 | ||
| 127 | if w, ok := st.Width(); ok { | |
| 128 | if l := b.Len(); l < w { | |
| 129 | pad := strings.Repeat(" ", w-l) | |
| 130 | if st.Flag('-') { | |
| 131 | b.WriteString(pad) | |
| 132 | } else { | |
| 133 | tmp := b.String() | |
| 134 | b.Reset() | |
| 135 | b.WriteString(pad) | |
| 136 | b.WriteString(tmp) | |
| 137 | } | |
| 138 | } | |
| 139 | } | |
| 140 | ||
| 141 | io.WriteString(st, b.String()) | |
| 142 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "testing" | |
| 5 | ) | |
| 6 | ||
| 7 | func TestB1024(t *testing.T) { | |
| 8 | cases := map[string]struct { | |
| 9 | value int64 | |
| 10 | verb string | |
| 11 | expected string | |
| 12 | }{ | |
| 13 | "verb %f": {12345678, "%f", "11.773756MiB"}, | |
| 14 | "verb %.0f": {12345678, "%.0f", "12MiB"}, | |
| 15 | "verb %.1f": {12345678, "%.1f", "11.8MiB"}, | |
| 16 | "verb %.2f": {12345678, "%.2f", "11.77MiB"}, | |
| 17 | "verb %.3f": {12345678, "%.3f", "11.774MiB"}, | |
| 18 | ||
| 19 | "verb % f": {12345678, "% f", "11.773756 MiB"}, | |
| 20 | "verb % .0f": {12345678, "% .0f", "12 MiB"}, | |
| 21 | "verb % .1f": {12345678, "% .1f", "11.8 MiB"}, | |
| 22 | "verb % .2f": {12345678, "% .2f", "11.77 MiB"}, | |
| 23 | "verb % .3f": {12345678, "% .3f", "11.774 MiB"}, | |
| 24 | ||
| 25 | "verb %8.f": {12345678, "%8.f", " 12MiB"}, | |
| 26 | "verb %8.0f": {12345678, "%8.0f", " 12MiB"}, | |
| 27 | "verb %8.1f": {12345678, "%8.1f", " 11.8MiB"}, | |
| 28 | "verb %8.2f": {12345678, "%8.2f", "11.77MiB"}, | |
| 29 | "verb %8.3f": {12345678, "%8.3f", "11.774MiB"}, | |
| 30 | ||
| 31 | "verb % 8.f": {12345678, "% 8.f", " 12 MiB"}, | |
| 32 | "verb % 8.0f": {12345678, "% 8.0f", " 12 MiB"}, | |
| 33 | "verb % 8.1f": {12345678, "% 8.1f", "11.8 MiB"}, | |
| 34 | ||
| 35 | "verb %-8.f": {12345678, "%-8.f", "12MiB "}, | |
| 36 | "verb %-8.0f": {12345678, "%-8.0f", "12MiB "}, | |
| 37 | "verb %-8.1f": {12345678, "%-8.1f", "11.8MiB "}, | |
| 38 | "verb %-8.2f": {12345678, "%8.2f", "11.77MiB"}, | |
| 39 | "verb %-8.3f": {12345678, "%8.3f", "11.774MiB"}, | |
| 40 | ||
| 41 | "verb % -8.f": {12345678, "% -8.f", "12 MiB "}, | |
| 42 | "verb % -8.0f": {12345678, "% -8.0f", "12 MiB "}, | |
| 43 | "verb % -8.1f": {12345678, "% -8.1f", "11.8 MiB"}, | |
| 44 | ||
| 45 | "1000 %f": {1000, "%f", "1000.000000b"}, | |
| 46 | "1000 %d": {1000, "%d", "1000b"}, | |
| 47 | "1000 %s": {1000, "%s", "1000b"}, | |
| 48 | "1024 %f": {1024, "%f", "1.000000KiB"}, | |
| 49 | "1024 %d": {1024, "%d", "1KiB"}, | |
| 50 | "1024 %.1f": {1024, "%.1f", "1.0KiB"}, | |
| 51 | "1024 %s": {1024, "%s", "1KiB"}, | |
| 52 | "3*MiB+140KiB %f": {3*int64(_iMiB) + 140*int64(_iKiB), "%f", "3.136719MiB"}, | |
| 53 | "3*MiB+140KiB %d": {3*int64(_iMiB) + 140*int64(_iKiB), "%d", "3MiB"}, | |
| 54 | "3*MiB+140KiB %.1f": {3*int64(_iMiB) + 140*int64(_iKiB), "%.1f", "3.1MiB"}, | |
| 55 | "3*MiB+140KiB %s": {3*int64(_iMiB) + 140*int64(_iKiB), "%s", "3.13671875MiB"}, | |
| 56 | "2*GiB %f": {2 * int64(_iGiB), "%f", "2.000000GiB"}, | |
| 57 | "2*GiB %d": {2 * int64(_iGiB), "%d", "2GiB"}, | |
| 58 | "2*GiB %.1f": {2 * int64(_iGiB), "%.1f", "2.0GiB"}, | |
| 59 | "2*GiB %s": {2 * int64(_iGiB), "%s", "2GiB"}, | |
| 60 | "4*TiB %f": {4 * int64(_iTiB), "%f", "4.000000TiB"}, | |
| 61 | "4*TiB %d": {4 * int64(_iTiB), "%d", "4TiB"}, | |
| 62 | "4*TiB %.1f": {4 * int64(_iTiB), "%.1f", "4.0TiB"}, | |
| 63 | "4*TiB %s": {4 * int64(_iTiB), "%s", "4TiB"}, | |
| 64 | } | |
| 65 | for name, tc := range cases { | |
| 66 | t.Run(name, func(t *testing.T) { | |
| 67 | got := fmt.Sprintf(tc.verb, SizeB1024(tc.value)) | |
| 68 | if got != tc.expected { | |
| 69 | t.Fatalf("expected: %q, got: %q\n", tc.expected, got) | |
| 70 | } | |
| 71 | }) | |
| 72 | } | |
| 73 | } | |
| 74 | ||
| 75 | func TestB1000(t *testing.T) { | |
| 76 | cases := map[string]struct { | |
| 77 | value int64 | |
| 78 | verb string | |
| 79 | expected string | |
| 80 | }{ | |
| 81 | "verb %f": {12345678, "%f", "12.345678MB"}, | |
| 82 | "verb %.0f": {12345678, "%.0f", "12MB"}, | |
| 83 | "verb %.1f": {12345678, "%.1f", "12.3MB"}, | |
| 84 | "verb %.2f": {12345678, "%.2f", "12.35MB"}, | |
| 85 | "verb %.3f": {12345678, "%.3f", "12.346MB"}, | |
| 86 | ||
| 87 | "verb % f": {12345678, "% f", "12.345678 MB"}, | |
| 88 | "verb % .0f": {12345678, "% .0f", "12 MB"}, | |
| 89 | "verb % .1f": {12345678, "% .1f", "12.3 MB"}, | |
| 90 | "verb % .2f": {12345678, "% .2f", "12.35 MB"}, | |
| 91 | "verb % .3f": {12345678, "% .3f", "12.346 MB"}, | |
| 92 | ||
| 93 | "verb %8.f": {12345678, "%8.f", " 12MB"}, | |
| 94 | "verb %8.0f": {12345678, "%8.0f", " 12MB"}, | |
| 95 | "verb %8.1f": {12345678, "%8.1f", " 12.3MB"}, | |
| 96 | "verb %8.2f": {12345678, "%8.2f", " 12.35MB"}, | |
| 97 | "verb %8.3f": {12345678, "%8.3f", "12.346MB"}, | |
| 98 | ||
| 99 | "verb % 8.f": {12345678, "% 8.f", " 12 MB"}, | |
| 100 | "verb % 8.0f": {12345678, "% 8.0f", " 12 MB"}, | |
| 101 | "verb % 8.1f": {12345678, "% 8.1f", " 12.3 MB"}, | |
| 102 | ||
| 103 | "verb %-8.f": {12345678, "%-8.f", "12MB "}, | |
| 104 | "verb %-8.0f": {12345678, "%-8.0f", "12MB "}, | |
| 105 | "verb %-8.1f": {12345678, "%-8.1f", "12.3MB "}, | |
| 106 | "verb %-8.2f": {12345678, "%8.2f", " 12.35MB"}, | |
| 107 | "verb %-8.3f": {12345678, "%8.3f", "12.346MB"}, | |
| 108 | ||
| 109 | "verb % -8.f": {12345678, "% -8.f", "12 MB "}, | |
| 110 | "verb % -8.0f": {12345678, "% -8.0f", "12 MB "}, | |
| 111 | "verb % -8.1f": {12345678, "% -8.1f", "12.3 MB "}, | |
| 112 | ||
| 113 | "1000 %f": {1000, "%f", "1.000000KB"}, | |
| 114 | "1000 %d": {1000, "%d", "1KB"}, | |
| 115 | "1000 %s": {1000, "%s", "1KB"}, | |
| 116 | "1024 %f": {1024, "%f", "1.024000KB"}, | |
| 117 | "1024 %d": {1024, "%d", "1KB"}, | |
| 118 | "1024 %.1f": {1024, "%.1f", "1.0KB"}, | |
| 119 | "1024 %s": {1024, "%s", "1.024KB"}, | |
| 120 | "3*MB+140*KB %f": {3*int64(_MB) + 140*int64(_KB), "%f", "3.140000MB"}, | |
| 121 | "3*MB+140*KB %d": {3*int64(_MB) + 140*int64(_KB), "%d", "3MB"}, | |
| 122 | "3*MB+140*KB %.1f": {3*int64(_MB) + 140*int64(_KB), "%.1f", "3.1MB"}, | |
| 123 | "3*MB+140*KB %s": {3*int64(_MB) + 140*int64(_KB), "%s", "3.14MB"}, | |
| 124 | "2*GB %f": {2 * int64(_GB), "%f", "2.000000GB"}, | |
| 125 | "2*GB %d": {2 * int64(_GB), "%d", "2GB"}, | |
| 126 | "2*GB %.1f": {2 * int64(_GB), "%.1f", "2.0GB"}, | |
| 127 | "2*GB %s": {2 * int64(_GB), "%s", "2GB"}, | |
| 128 | "4*TB %f": {4 * int64(_TB), "%f", "4.000000TB"}, | |
| 129 | "4*TB %d": {4 * int64(_TB), "%d", "4TB"}, | |
| 130 | "4*TB %.1f": {4 * int64(_TB), "%.1f", "4.0TB"}, | |
| 131 | "4*TB %s": {4 * int64(_TB), "%s", "4TB"}, | |
| 132 | } | |
| 133 | for name, tc := range cases { | |
| 134 | t.Run(name, func(t *testing.T) { | |
| 135 | got := fmt.Sprintf(tc.verb, SizeB1000(tc.value)) | |
| 136 | if got != tc.expected { | |
| 137 | t.Fatalf("expected: %q, got: %q\n", tc.expected, got) | |
| 138 | } | |
| 139 | }) | |
| 140 | } | |
| 141 | } |
| 0 | // Code generated by "stringer -type=SizeB1000 -trimprefix=_"; DO NOT EDIT. | |
| 1 | ||
| 2 | package decor | |
| 3 | ||
| 4 | import "strconv" | |
| 5 | ||
| 6 | func _() { | |
| 7 | // An "invalid array index" compiler error signifies that the constant values have changed. | |
| 8 | // Re-run the stringer command to generate them again. | |
| 9 | var x [1]struct{} | |
| 10 | _ = x[_b-0] | |
| 11 | _ = x[_KB-1000] | |
| 12 | _ = x[_MB-1000000] | |
| 13 | _ = x[_GB-1000000000] | |
| 14 | _ = x[_TB-1000000000000] | |
| 15 | } | |
| 16 | ||
| 17 | const ( | |
| 18 | _SizeB1000_name_0 = "b" | |
| 19 | _SizeB1000_name_1 = "KB" | |
| 20 | _SizeB1000_name_2 = "MB" | |
| 21 | _SizeB1000_name_3 = "GB" | |
| 22 | _SizeB1000_name_4 = "TB" | |
| 23 | ) | |
| 24 | ||
| 25 | func (i SizeB1000) String() string { | |
| 26 | switch { | |
| 27 | case i == 0: | |
| 28 | return _SizeB1000_name_0 | |
| 29 | case i == 1000: | |
| 30 | return _SizeB1000_name_1 | |
| 31 | case i == 1000000: | |
| 32 | return _SizeB1000_name_2 | |
| 33 | case i == 1000000000: | |
| 34 | return _SizeB1000_name_3 | |
| 35 | case i == 1000000000000: | |
| 36 | return _SizeB1000_name_4 | |
| 37 | default: | |
| 38 | return "SizeB1000(" + strconv.FormatInt(int64(i), 10) + ")" | |
| 39 | } | |
| 40 | } |
| 0 | // Code generated by "stringer -type=SizeB1024 -trimprefix=_i"; DO NOT EDIT. | |
| 1 | ||
| 2 | package decor | |
| 3 | ||
| 4 | import "strconv" | |
| 5 | ||
| 6 | func _() { | |
| 7 | // An "invalid array index" compiler error signifies that the constant values have changed. | |
| 8 | // Re-run the stringer command to generate them again. | |
| 9 | var x [1]struct{} | |
| 10 | _ = x[_ib-0] | |
| 11 | _ = x[_iKiB-1024] | |
| 12 | _ = x[_iMiB-1048576] | |
| 13 | _ = x[_iGiB-1073741824] | |
| 14 | _ = x[_iTiB-1099511627776] | |
| 15 | } | |
| 16 | ||
| 17 | const ( | |
| 18 | _SizeB1024_name_0 = "b" | |
| 19 | _SizeB1024_name_1 = "KiB" | |
| 20 | _SizeB1024_name_2 = "MiB" | |
| 21 | _SizeB1024_name_3 = "GiB" | |
| 22 | _SizeB1024_name_4 = "TiB" | |
| 23 | ) | |
| 24 | ||
| 25 | func (i SizeB1024) String() string { | |
| 26 | switch { | |
| 27 | case i == 0: | |
| 28 | return _SizeB1024_name_0 | |
| 29 | case i == 1024: | |
| 30 | return _SizeB1024_name_1 | |
| 31 | case i == 1048576: | |
| 32 | return _SizeB1024_name_2 | |
| 33 | case i == 1073741824: | |
| 34 | return _SizeB1024_name_3 | |
| 35 | case i == 1099511627776: | |
| 36 | return _SizeB1024_name_4 | |
| 37 | default: | |
| 38 | return "SizeB1024(" + strconv.FormatInt(int64(i), 10) + ")" | |
| 39 | } | |
| 40 | } |
| 1 | 1 | |
| 2 | 2 | import ( |
| 3 | 3 | "fmt" |
| 4 | "io" | |
| 5 | 4 | "math" |
| 6 | "strconv" | |
| 7 | "strings" | |
| 8 | 5 | "time" |
| 9 | 6 | |
| 10 | 7 | "github.com/VividCortex/ewma" |
| 11 | 8 | ) |
| 12 | ||
| 13 | type SpeedKiB float64 | |
| 14 | ||
| 15 | func (s SpeedKiB) Format(st fmt.State, verb rune) { | |
| 16 | var prec int | |
| 17 | switch verb { | |
| 18 | case 'd': | |
| 19 | case 's': | |
| 20 | prec = -1 | |
| 21 | default: | |
| 22 | if p, ok := st.Precision(); ok { | |
| 23 | prec = p | |
| 24 | } else { | |
| 25 | prec = 6 | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | var res, unit string | |
| 30 | switch { | |
| 31 | case s >= TiB: | |
| 32 | unit = "TiB/s" | |
| 33 | res = strconv.FormatFloat(float64(s)/TiB, 'f', prec, 64) | |
| 34 | case s >= GiB: | |
| 35 | unit = "GiB/s" | |
| 36 | res = strconv.FormatFloat(float64(s)/GiB, 'f', prec, 64) | |
| 37 | case s >= MiB: | |
| 38 | unit = "MiB/s" | |
| 39 | res = strconv.FormatFloat(float64(s)/MiB, 'f', prec, 64) | |
| 40 | case s >= KiB: | |
| 41 | unit = "KiB/s" | |
| 42 | res = strconv.FormatFloat(float64(s)/KiB, 'f', prec, 64) | |
| 43 | default: | |
| 44 | unit = "b/s" | |
| 45 | res = strconv.FormatInt(int64(s), 10) | |
| 46 | } | |
| 47 | ||
| 48 | if st.Flag(' ') { | |
| 49 | res += " " | |
| 50 | } | |
| 51 | res += unit | |
| 52 | ||
| 53 | if w, ok := st.Width(); ok { | |
| 54 | if len(res) < w { | |
| 55 | pad := strings.Repeat(" ", w-len(res)) | |
| 56 | if st.Flag('-') { | |
| 57 | res += pad | |
| 58 | } else { | |
| 59 | res = pad + res | |
| 60 | } | |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | io.WriteString(st, res) | |
| 65 | } | |
| 66 | ||
| 67 | type SpeedKB float64 | |
| 68 | ||
| 69 | func (s SpeedKB) Format(st fmt.State, verb rune) { | |
| 70 | var prec int | |
| 71 | switch verb { | |
| 72 | case 'd': | |
| 73 | case 's': | |
| 74 | prec = -1 | |
| 75 | default: | |
| 76 | if p, ok := st.Precision(); ok { | |
| 77 | prec = p | |
| 78 | } else { | |
| 79 | prec = 6 | |
| 80 | } | |
| 81 | } | |
| 82 | ||
| 83 | var res, unit string | |
| 84 | switch { | |
| 85 | case s >= TB: | |
| 86 | unit = "TB/s" | |
| 87 | res = strconv.FormatFloat(float64(s)/TB, 'f', prec, 64) | |
| 88 | case s >= GB: | |
| 89 | unit = "GB/s" | |
| 90 | res = strconv.FormatFloat(float64(s)/GB, 'f', prec, 64) | |
| 91 | case s >= MB: | |
| 92 | unit = "MB/s" | |
| 93 | res = strconv.FormatFloat(float64(s)/MB, 'f', prec, 64) | |
| 94 | case s >= KB: | |
| 95 | unit = "kB/s" | |
| 96 | res = strconv.FormatFloat(float64(s)/KB, 'f', prec, 64) | |
| 97 | default: | |
| 98 | unit = "b/s" | |
| 99 | res = strconv.FormatInt(int64(s), 10) | |
| 100 | } | |
| 101 | ||
| 102 | if st.Flag(' ') { | |
| 103 | res += " " | |
| 104 | } | |
| 105 | res += unit | |
| 106 | ||
| 107 | if w, ok := st.Width(); ok { | |
| 108 | if len(res) < w { | |
| 109 | pad := strings.Repeat(" ", w-len(res)) | |
| 110 | if st.Flag(int('-')) { | |
| 111 | res += pad | |
| 112 | } else { | |
| 113 | res = pad + res | |
| 114 | } | |
| 115 | } | |
| 116 | } | |
| 117 | ||
| 118 | io.WriteString(st, res) | |
| 119 | } | |
| 120 | 9 | |
| 121 | 10 | // EwmaSpeed exponential-weighted-moving-average based speed decorator. |
| 122 | 11 | // Note that it's necessary to supply bar.Incr* methods with incremental |
| 150 | 39 | wc = widthConf |
| 151 | 40 | } |
| 152 | 41 | wc.Init() |
| 42 | switch unit { | |
| 43 | case UnitKiB, UnitKB: | |
| 44 | fmt += "/s" | |
| 45 | } | |
| 153 | 46 | d := &movingAverageSpeed{ |
| 154 | 47 | WC: wc, |
| 155 | 48 | unit: unit, |
| 177 | 70 | } |
| 178 | 71 | |
| 179 | 72 | speed := d.average.Value() |
| 73 | ||
| 180 | 74 | switch d.unit { |
| 181 | 75 | case UnitKiB: |
| 182 | d.msg = fmt.Sprintf(d.fmt, SpeedKiB(speed)) | |
| 76 | d.msg = fmt.Sprintf(d.fmt, SizeB1024(math.Round(speed))) | |
| 183 | 77 | case UnitKB: |
| 184 | d.msg = fmt.Sprintf(d.fmt, SpeedKB(speed)) | |
| 78 | d.msg = fmt.Sprintf(d.fmt, SizeB1000(math.Round(speed))) | |
| 185 | 79 | default: |
| 186 | 80 | d.msg = fmt.Sprintf(d.fmt, speed) |
| 187 | 81 | } |
| 235 | 129 | wc = widthConf |
| 236 | 130 | } |
| 237 | 131 | wc.Init() |
| 132 | switch unit { | |
| 133 | case UnitKiB, UnitKB: | |
| 134 | fmt += "/s" | |
| 135 | } | |
| 238 | 136 | d := &averageSpeed{ |
| 239 | 137 | WC: wc, |
| 240 | 138 | unit: unit, |
| 139 | startTime: startTime, | |
| 241 | 140 | fmt: fmt, |
| 242 | startTime: startTime, | |
| 243 | 141 | } |
| 244 | 142 | return d |
| 245 | 143 | } |
| 247 | 145 | type averageSpeed struct { |
| 248 | 146 | WC |
| 249 | 147 | unit int |
| 148 | startTime time.Time | |
| 250 | 149 | fmt string |
| 251 | startTime time.Time | |
| 252 | 150 | msg string |
| 253 | 151 | completeMsg *string |
| 254 | 152 | } |
| 266 | 164 | |
| 267 | 165 | switch d.unit { |
| 268 | 166 | case UnitKiB: |
| 269 | d.msg = fmt.Sprintf(d.fmt, SpeedKiB(speed)) | |
| 167 | d.msg = fmt.Sprintf(d.fmt, SizeB1024(math.Round(speed))) | |
| 270 | 168 | case UnitKB: |
| 271 | d.msg = fmt.Sprintf(d.fmt, SpeedKB(speed)) | |
| 169 | d.msg = fmt.Sprintf(d.fmt, SizeB1000(math.Round(speed))) | |
| 272 | 170 | default: |
| 273 | 171 | d.msg = fmt.Sprintf(d.fmt, speed) |
| 274 | 172 | } |
| 0 | 0 | package decor |
| 1 | 1 | |
| 2 | 2 | import ( |
| 3 | "fmt" | |
| 4 | 3 | "testing" |
| 4 | "time" | |
| 5 | 5 | ) |
| 6 | 6 | |
| 7 | func TestSpeedKiB(t *testing.T) { | |
| 8 | cases := map[string]struct { | |
| 9 | value int64 | |
| 10 | verb string | |
| 7 | func TestSpeedKiBDecor(t *testing.T) { | |
| 8 | cases := []struct { | |
| 9 | name string | |
| 10 | fmt string | |
| 11 | unit int | |
| 12 | current int64 | |
| 13 | elapsed time.Duration | |
| 11 | 14 | expected string |
| 12 | 15 | }{ |
| 13 | "verb %f": {12345678, "%f", "11.773756MiB/s"}, | |
| 14 | "verb %.0f": {12345678, "%.0f", "12MiB/s"}, | |
| 15 | "verb %.1f": {12345678, "%.1f", "11.8MiB/s"}, | |
| 16 | "verb %.2f": {12345678, "%.2f", "11.77MiB/s"}, | |
| 17 | "verb %.3f": {12345678, "%.3f", "11.774MiB/s"}, | |
| 18 | ||
| 19 | "verb % f": {12345678, "% f", "11.773756 MiB/s"}, | |
| 20 | "verb % .0f": {12345678, "% .0f", "12 MiB/s"}, | |
| 21 | "verb % .1f": {12345678, "% .1f", "11.8 MiB/s"}, | |
| 22 | "verb % .2f": {12345678, "% .2f", "11.77 MiB/s"}, | |
| 23 | "verb % .3f": {12345678, "% .3f", "11.774 MiB/s"}, | |
| 24 | ||
| 25 | "verb %10.f": {12345678, "%10.f", " 12MiB/s"}, | |
| 26 | "verb %10.0f": {12345678, "%10.0f", " 12MiB/s"}, | |
| 27 | "verb %10.1f": {12345678, "%10.1f", " 11.8MiB/s"}, | |
| 28 | "verb %10.2f": {12345678, "%10.2f", "11.77MiB/s"}, | |
| 29 | "verb %10.3f": {12345678, "%10.3f", "11.774MiB/s"}, | |
| 30 | ||
| 31 | "verb % 10.f": {12345678, "% 10.f", " 12 MiB/s"}, | |
| 32 | "verb % 10.0f": {12345678, "% 10.0f", " 12 MiB/s"}, | |
| 33 | "verb % 10.1f": {12345678, "% 10.1f", "11.8 MiB/s"}, | |
| 34 | ||
| 35 | "verb %-10.f": {12345678, "%-10.f", "12MiB/s "}, | |
| 36 | "verb %-10.0f": {12345678, "%-10.0f", "12MiB/s "}, | |
| 37 | "verb %-10.1f": {12345678, "%-10.1f", "11.8MiB/s "}, | |
| 38 | "verb %-10.2f": {12345678, "%10.2f", "11.77MiB/s"}, | |
| 39 | "verb %-10.3f": {12345678, "%10.3f", "11.774MiB/s"}, | |
| 40 | ||
| 41 | "verb % -10.f": {12345678, "% -10.f", "12 MiB/s "}, | |
| 42 | "verb % -10.0f": {12345678, "% -10.0f", "12 MiB/s "}, | |
| 43 | "verb % -10.1f": {12345678, "% -10.1f", "11.8 MiB/s"}, | |
| 44 | ||
| 45 | "1000 %f": {1000, "%f", "1000b/s"}, | |
| 46 | "1000 %d": {1000, "%d", "1000b/s"}, | |
| 47 | "1000 %s": {1000, "%s", "1000b/s"}, | |
| 48 | "1024 %f": {1024, "%f", "1.000000KiB/s"}, | |
| 49 | "1024 %d": {1024, "%d", "1KiB/s"}, | |
| 50 | "1024 %.1f": {1024, "%.1f", "1.0KiB/s"}, | |
| 51 | "1024 %s": {1024, "%s", "1KiB/s"}, | |
| 52 | "3*MiB/s+140KiB/s %f": {3*MiB + 140*KiB, "%f", "3.136719MiB/s"}, | |
| 53 | "3*MiB/s+140KiB/s %d": {3*MiB + 140*KiB, "%d", "3MiB/s"}, | |
| 54 | "3*MiB/s+140KiB/s %.1f": {3*MiB + 140*KiB, "%.1f", "3.1MiB/s"}, | |
| 55 | "3*MiB/s+140KiB/s %s": {3*MiB + 140*KiB, "%s", "3.13671875MiB/s"}, | |
| 56 | "2*GiB/s %f": {2 * GiB, "%f", "2.000000GiB/s"}, | |
| 57 | "2*GiB/s %d": {2 * GiB, "%d", "2GiB/s"}, | |
| 58 | "2*GiB/s %.1f": {2 * GiB, "%.1f", "2.0GiB/s"}, | |
| 59 | "2*GiB/s %s": {2 * GiB, "%s", "2GiB/s"}, | |
| 60 | "4*TiB/s %f": {4 * TiB, "%f", "4.000000TiB/s"}, | |
| 61 | "4*TiB/s %d": {4 * TiB, "%d", "4TiB/s"}, | |
| 62 | "4*TiB/s %.1f": {4 * TiB, "%.1f", "4.0TiB/s"}, | |
| 63 | "4*TiB/s %s": {4 * TiB, "%s", "4TiB/s"}, | |
| 64 | } | |
| 65 | for name, tc := range cases { | |
| 66 | t.Run(name, func(t *testing.T) { | |
| 67 | got := fmt.Sprintf(tc.verb, SpeedKiB(tc.value)) | |
| 68 | if got != tc.expected { | |
| 69 | t.Fatalf("expected: %q, got: %q\n", tc.expected, got) | |
| 16 | { | |
| 17 | name: "UnitKiB:%d:0b", | |
| 18 | unit: UnitKiB, | |
| 19 | fmt: "%d", | |
| 20 | current: 0, | |
| 21 | elapsed: time.Second, | |
| 22 | expected: "0b/s", | |
| 23 | }, | |
| 24 | { | |
| 25 | name: "UnitKiB:% .2f:0b", | |
| 26 | unit: UnitKiB, | |
| 27 | fmt: "% .2f", | |
| 28 | current: 0, | |
| 29 | elapsed: time.Second, | |
| 30 | expected: "0.00 b/s", | |
| 31 | }, | |
| 32 | { | |
| 33 | name: "UnitKiB:%d:1b", | |
| 34 | unit: UnitKiB, | |
| 35 | fmt: "%d", | |
| 36 | current: 1, | |
| 37 | elapsed: time.Second, | |
| 38 | expected: "1b/s", | |
| 39 | }, | |
| 40 | { | |
| 41 | name: "UnitKiB:% .2f:1b", | |
| 42 | unit: UnitKiB, | |
| 43 | fmt: "% .2f", | |
| 44 | current: 1, | |
| 45 | elapsed: time.Second, | |
| 46 | expected: "1.00 b/s", | |
| 47 | }, | |
| 48 | { | |
| 49 | name: "UnitKiB:%d:KiB", | |
| 50 | unit: UnitKiB, | |
| 51 | fmt: "%d", | |
| 52 | current: 2 * int64(_iKiB), | |
| 53 | elapsed: 1 * time.Second, | |
| 54 | expected: "2KiB/s", | |
| 55 | }, | |
| 56 | { | |
| 57 | name: "UnitKiB:% .f:KiB", | |
| 58 | unit: UnitKiB, | |
| 59 | fmt: "% .2f", | |
| 60 | current: 2 * int64(_iKiB), | |
| 61 | elapsed: 1 * time.Second, | |
| 62 | expected: "2.00 KiB/s", | |
| 63 | }, | |
| 64 | { | |
| 65 | name: "UnitKiB:%d:MiB", | |
| 66 | unit: UnitKiB, | |
| 67 | fmt: "%d", | |
| 68 | current: 2 * int64(_iMiB), | |
| 69 | elapsed: 1 * time.Second, | |
| 70 | expected: "2MiB/s", | |
| 71 | }, | |
| 72 | { | |
| 73 | name: "UnitKiB:% .2f:MiB", | |
| 74 | unit: UnitKiB, | |
| 75 | fmt: "% .2f", | |
| 76 | current: 2 * int64(_iMiB), | |
| 77 | elapsed: 1 * time.Second, | |
| 78 | expected: "2.00 MiB/s", | |
| 79 | }, | |
| 80 | { | |
| 81 | name: "UnitKiB:%d:GiB", | |
| 82 | unit: UnitKiB, | |
| 83 | fmt: "%d", | |
| 84 | current: 2 * int64(_iGiB), | |
| 85 | elapsed: 1 * time.Second, | |
| 86 | expected: "2GiB/s", | |
| 87 | }, | |
| 88 | { | |
| 89 | name: "UnitKiB:% .2f:GiB", | |
| 90 | unit: UnitKiB, | |
| 91 | fmt: "% .2f", | |
| 92 | current: 2 * int64(_iGiB), | |
| 93 | elapsed: 1 * time.Second, | |
| 94 | expected: "2.00 GiB/s", | |
| 95 | }, | |
| 96 | { | |
| 97 | name: "UnitKiB:%d:TiB", | |
| 98 | unit: UnitKiB, | |
| 99 | fmt: "%d", | |
| 100 | current: 2 * int64(_iTiB), | |
| 101 | elapsed: 1 * time.Second, | |
| 102 | expected: "2TiB/s", | |
| 103 | }, | |
| 104 | { | |
| 105 | name: "UnitKiB:% .2f:TiB", | |
| 106 | unit: UnitKiB, | |
| 107 | fmt: "% .2f", | |
| 108 | current: 2 * int64(_iTiB), | |
| 109 | elapsed: 1 * time.Second, | |
| 110 | expected: "2.00 TiB/s", | |
| 111 | }, | |
| 112 | } | |
| 113 | for _, tc := range cases { | |
| 114 | t.Run(tc.name, func(t *testing.T) { | |
| 115 | decor := NewAverageSpeed(tc.unit, tc.fmt, time.Now().Add(-tc.elapsed)) | |
| 116 | stat := &Statistics{ | |
| 117 | Current: tc.current, | |
| 118 | } | |
| 119 | res := decor.Decor(stat) | |
| 120 | if res != tc.expected { | |
| 121 | t.Fatalf("expected: %q, got: %q\n", tc.expected, res) | |
| 70 | 122 | } |
| 71 | 123 | }) |
| 72 | 124 | } |
| 73 | 125 | } |
| 74 | 126 | |
| 75 | func TestSpeedKB(t *testing.T) { | |
| 76 | cases := map[string]struct { | |
| 77 | value int64 | |
| 78 | verb string | |
| 127 | func TestSpeedKBDecor(t *testing.T) { | |
| 128 | cases := []struct { | |
| 129 | name string | |
| 130 | fmt string | |
| 131 | unit int | |
| 132 | current int64 | |
| 133 | elapsed time.Duration | |
| 79 | 134 | expected string |
| 80 | 135 | }{ |
| 81 | "verb %f": {12345678, "%f", "12.345678MB/s"}, | |
| 82 | "verb %.0f": {12345678, "%.0f", "12MB/s"}, | |
| 83 | "verb %.1f": {12345678, "%.1f", "12.3MB/s"}, | |
| 84 | "verb %.2f": {12345678, "%.2f", "12.35MB/s"}, | |
| 85 | "verb %.3f": {12345678, "%.3f", "12.346MB/s"}, | |
| 86 | ||
| 87 | "verb % f": {12345678, "% f", "12.345678 MB/s"}, | |
| 88 | "verb % .0f": {12345678, "% .0f", "12 MB/s"}, | |
| 89 | "verb % .1f": {12345678, "% .1f", "12.3 MB/s"}, | |
| 90 | "verb % .2f": {12345678, "% .2f", "12.35 MB/s"}, | |
| 91 | "verb % .3f": {12345678, "% .3f", "12.346 MB/s"}, | |
| 92 | ||
| 93 | "verb %10.f": {12345678, "%10.f", " 12MB/s"}, | |
| 94 | "verb %10.0f": {12345678, "%10.0f", " 12MB/s"}, | |
| 95 | "verb %10.1f": {12345678, "%10.1f", " 12.3MB/s"}, | |
| 96 | "verb %10.2f": {12345678, "%10.2f", " 12.35MB/s"}, | |
| 97 | "verb %10.3f": {12345678, "%10.3f", "12.346MB/s"}, | |
| 98 | ||
| 99 | "verb % 10.f": {12345678, "% 10.f", " 12 MB/s"}, | |
| 100 | "verb % 10.0f": {12345678, "% 10.0f", " 12 MB/s"}, | |
| 101 | "verb % 10.1f": {12345678, "% 10.1f", " 12.3 MB/s"}, | |
| 102 | ||
| 103 | "verb %-10.f": {12345678, "%-10.f", "12MB/s "}, | |
| 104 | "verb %-10.0f": {12345678, "%-10.0f", "12MB/s "}, | |
| 105 | "verb %-10.1f": {12345678, "%-10.1f", "12.3MB/s "}, | |
| 106 | "verb %-10.2f": {12345678, "%10.2f", " 12.35MB/s"}, | |
| 107 | "verb %-10.3f": {12345678, "%10.3f", "12.346MB/s"}, | |
| 108 | ||
| 109 | "verb % -10.f": {12345678, "% -10.f", "12 MB/s "}, | |
| 110 | "verb % -10.0f": {12345678, "% -10.0f", "12 MB/s "}, | |
| 111 | "verb % -10.1f": {12345678, "% -10.1f", "12.3 MB/s "}, | |
| 112 | ||
| 113 | "1000 %f": {1000, "%f", "1.000000kB/s"}, | |
| 114 | "1000 %d": {1000, "%d", "1kB/s"}, | |
| 115 | "1000 %s": {1000, "%s", "1kB/s"}, | |
| 116 | "1024 %f": {1024, "%f", "1.024000kB/s"}, | |
| 117 | "1024 %d": {1024, "%d", "1kB/s"}, | |
| 118 | "1024 %.1f": {1024, "%.1f", "1.0kB/s"}, | |
| 119 | "1024 %s": {1024, "%s", "1.024kB/s"}, | |
| 120 | "3*MB/s+140*KB/s %f": {3*MB + 140*KB, "%f", "3.140000MB/s"}, | |
| 121 | "3*MB/s+140*KB/s %d": {3*MB + 140*KB, "%d", "3MB/s"}, | |
| 122 | "3*MB/s+140*KB/s %.1f": {3*MB + 140*KB, "%.1f", "3.1MB/s"}, | |
| 123 | "3*MB/s+140*KB/s %s": {3*MB + 140*KB, "%s", "3.14MB/s"}, | |
| 124 | "2*GB/s %f": {2 * GB, "%f", "2.000000GB/s"}, | |
| 125 | "2*GB/s %d": {2 * GB, "%d", "2GB/s"}, | |
| 126 | "2*GB/s %.1f": {2 * GB, "%.1f", "2.0GB/s"}, | |
| 127 | "2*GB/s %s": {2 * GB, "%s", "2GB/s"}, | |
| 128 | "4*TB/s %f": {4 * TB, "%f", "4.000000TB/s"}, | |
| 129 | "4*TB/s %d": {4 * TB, "%d", "4TB/s"}, | |
| 130 | "4*TB/s %.1f": {4 * TB, "%.1f", "4.0TB/s"}, | |
| 131 | "4*TB/s %s": {4 * TB, "%s", "4TB/s"}, | |
| 132 | } | |
| 133 | for name, tc := range cases { | |
| 134 | t.Run(name, func(t *testing.T) { | |
| 135 | got := fmt.Sprintf(tc.verb, SpeedKB(tc.value)) | |
| 136 | if got != tc.expected { | |
| 137 | t.Fatalf("expected: %q, got: %q\n", tc.expected, got) | |
| 136 | { | |
| 137 | name: "UnitKB:%d:0b", | |
| 138 | unit: UnitKB, | |
| 139 | fmt: "%d", | |
| 140 | current: 0, | |
| 141 | elapsed: time.Second, | |
| 142 | expected: "0b/s", | |
| 143 | }, | |
| 144 | { | |
| 145 | name: "UnitKB:% .2f:0b", | |
| 146 | unit: UnitKB, | |
| 147 | fmt: "% .2f", | |
| 148 | current: 0, | |
| 149 | elapsed: time.Second, | |
| 150 | expected: "0.00 b/s", | |
| 151 | }, | |
| 152 | { | |
| 153 | name: "UnitKB:%d:1b", | |
| 154 | unit: UnitKB, | |
| 155 | fmt: "%d", | |
| 156 | current: 1, | |
| 157 | elapsed: time.Second, | |
| 158 | expected: "1b/s", | |
| 159 | }, | |
| 160 | { | |
| 161 | name: "UnitKB:% .2f:1b", | |
| 162 | unit: UnitKB, | |
| 163 | fmt: "% .2f", | |
| 164 | current: 1, | |
| 165 | elapsed: time.Second, | |
| 166 | expected: "1.00 b/s", | |
| 167 | }, | |
| 168 | { | |
| 169 | name: "UnitKB:%d:KB", | |
| 170 | unit: UnitKB, | |
| 171 | fmt: "%d", | |
| 172 | current: 2 * int64(_KB), | |
| 173 | elapsed: 1 * time.Second, | |
| 174 | expected: "2KB/s", | |
| 175 | }, | |
| 176 | { | |
| 177 | name: "UnitKB:% .f:KB", | |
| 178 | unit: UnitKB, | |
| 179 | fmt: "% .2f", | |
| 180 | current: 2 * int64(_KB), | |
| 181 | elapsed: 1 * time.Second, | |
| 182 | expected: "2.00 KB/s", | |
| 183 | }, | |
| 184 | { | |
| 185 | name: "UnitKB:%d:MB", | |
| 186 | unit: UnitKB, | |
| 187 | fmt: "%d", | |
| 188 | current: 2 * int64(_MB), | |
| 189 | elapsed: 1 * time.Second, | |
| 190 | expected: "2MB/s", | |
| 191 | }, | |
| 192 | { | |
| 193 | name: "UnitKB:% .2f:MB", | |
| 194 | unit: UnitKB, | |
| 195 | fmt: "% .2f", | |
| 196 | current: 2 * int64(_MB), | |
| 197 | elapsed: 1 * time.Second, | |
| 198 | expected: "2.00 MB/s", | |
| 199 | }, | |
| 200 | { | |
| 201 | name: "UnitKB:%d:GB", | |
| 202 | unit: UnitKB, | |
| 203 | fmt: "%d", | |
| 204 | current: 2 * int64(_GB), | |
| 205 | elapsed: 1 * time.Second, | |
| 206 | expected: "2GB/s", | |
| 207 | }, | |
| 208 | { | |
| 209 | name: "UnitKB:% .2f:GB", | |
| 210 | unit: UnitKB, | |
| 211 | fmt: "% .2f", | |
| 212 | current: 2 * int64(_GB), | |
| 213 | elapsed: 1 * time.Second, | |
| 214 | expected: "2.00 GB/s", | |
| 215 | }, | |
| 216 | { | |
| 217 | name: "UnitKB:%d:TB", | |
| 218 | unit: UnitKB, | |
| 219 | fmt: "%d", | |
| 220 | current: 2 * int64(_TB), | |
| 221 | elapsed: 1 * time.Second, | |
| 222 | expected: "2TB/s", | |
| 223 | }, | |
| 224 | { | |
| 225 | name: "UnitKB:% .2f:TB", | |
| 226 | unit: UnitKB, | |
| 227 | fmt: "% .2f", | |
| 228 | current: 2 * int64(_TB), | |
| 229 | elapsed: 1 * time.Second, | |
| 230 | expected: "2.00 TB/s", | |
| 231 | }, | |
| 232 | } | |
| 233 | for _, tc := range cases { | |
| 234 | t.Run(tc.name, func(t *testing.T) { | |
| 235 | decor := NewAverageSpeed(tc.unit, tc.fmt, time.Now().Add(-tc.elapsed)) | |
| 236 | stat := &Statistics{ | |
| 237 | Current: tc.current, | |
| 238 | } | |
| 239 | res := decor.Decor(stat) | |
| 240 | if res != tc.expected { | |
| 241 | t.Fatalf("expected: %q, got: %q\n", tc.expected, res) | |
| 138 | 242 | } |
| 139 | 243 | }) |
| 140 | 244 | } |