Skip to content

Commit 4343749

Browse files
committed
Add a simple progressBar
1 parent 08c2e13 commit 4343749

File tree

2 files changed

+260
-0
lines changed

2 files changed

+260
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package com.eternalcode.commons.progressbar;
2+
3+
public class ProgressBar {
4+
5+
private final String filledToken;
6+
7+
private final String emptyToken;
8+
9+
private final boolean showBrackets;
10+
private final String leftBracket;
11+
private final String rightBracket;
12+
private final String bracketColor;
13+
14+
private final int length;
15+
16+
private ProgressBar(Builder builder) {
17+
String filledChar = builder.filledChar;
18+
String emptyChar = builder.emptyChar;
19+
String filledColor = builder.filledColor;
20+
String emptyColor = builder.emptyColor;
21+
22+
this.leftBracket = builder.leftBracket;
23+
this.rightBracket = builder.rightBracket;
24+
this.bracketColor = builder.bracketColor;
25+
this.length = builder.length;
26+
this.showBrackets = builder.showBrackets;
27+
28+
this.filledToken = filledColor + filledChar;
29+
this.emptyToken = emptyColor + emptyChar;
30+
}
31+
32+
public String render(double progress) {
33+
double clampedProgress = Math.max(0, Math.min(1, progress));
34+
int filled = (int) (this.length * clampedProgress);
35+
36+
StringBuilder bar = new StringBuilder();
37+
38+
if (this.showBrackets) {
39+
bar.append(this.bracketColor).append(this.leftBracket);
40+
}
41+
42+
bar.append(this.filledToken.repeat(filled));
43+
bar.append(this.emptyToken.repeat(this.length - filled));
44+
45+
if (this.showBrackets) {
46+
bar.append(this.bracketColor).append(this.rightBracket);
47+
}
48+
49+
return bar.toString();
50+
}
51+
52+
public String render(int current, int max) {
53+
if (max <= 0) {
54+
return this.render(1.0);
55+
}
56+
double progress = (double) current / max;
57+
return this.render(progress);
58+
}
59+
60+
public String render(long current, long max) {
61+
if (max <= 0) {
62+
return this.render(1.0);
63+
}
64+
double progress = (double) current / max;
65+
return this.render(progress);
66+
}
67+
68+
public static Builder builder() {
69+
return new Builder();
70+
}
71+
72+
public static class Builder {
73+
private String filledChar = "█";
74+
private String emptyChar = "░";
75+
private String filledColor = "";
76+
private String emptyColor = "";
77+
private String leftBracket = "[";
78+
private String rightBracket = "]";
79+
private String bracketColor = "";
80+
private int length = 10;
81+
private boolean showBrackets = true;
82+
83+
public Builder filledChar(String filledChar) {
84+
this.filledChar = filledChar;
85+
return this;
86+
}
87+
88+
public Builder emptyChar(String emptyChar) {
89+
this.emptyChar = emptyChar;
90+
return this;
91+
}
92+
93+
public Builder filledColor(String filledColor) {
94+
this.filledColor = filledColor;
95+
return this;
96+
}
97+
98+
public Builder emptyColor(String emptyColor) {
99+
this.emptyColor = emptyColor;
100+
return this;
101+
}
102+
103+
public Builder leftBracket(String leftBracket) {
104+
this.leftBracket = leftBracket;
105+
return this;
106+
}
107+
108+
public Builder rightBracket(String rightBracket) {
109+
this.rightBracket = rightBracket;
110+
return this;
111+
}
112+
113+
public Builder brackets(String left, String right) {
114+
this.leftBracket = left;
115+
this.rightBracket = right;
116+
return this;
117+
}
118+
119+
public Builder bracketColor(String bracketColor) {
120+
this.bracketColor = bracketColor;
121+
return this;
122+
}
123+
124+
public Builder length(int length) {
125+
if (length <= 0) {
126+
throw new IllegalArgumentException("Length must be positive");
127+
}
128+
this.length = length;
129+
return this;
130+
}
131+
132+
public Builder showBrackets(boolean showBrackets) {
133+
this.showBrackets = showBrackets;
134+
return this;
135+
}
136+
137+
public Builder hideBrackets() {
138+
this.showBrackets = false;
139+
return this;
140+
}
141+
142+
public ProgressBar build() {
143+
return new ProgressBar(this);
144+
}
145+
}
146+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package com.eternalcode.commons.progressbar;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.*;
6+
7+
class ProgressBarTest {
8+
9+
@Test
10+
void testRenderFullProgress() {
11+
ProgressBar bar = ProgressBar.builder()
12+
.length(5)
13+
.build();
14+
String rendered = bar.render(1.0);
15+
16+
assertTrue(rendered.contains("█"));
17+
assertFalse(rendered.contains("░"));
18+
assertEquals(7, rendered.length());
19+
}
20+
21+
@Test
22+
void testRenderEmptyProgress() {
23+
ProgressBar bar = ProgressBar.builder()
24+
.length(5)
25+
.build();
26+
String rendered = bar.render(0.0);
27+
28+
assertTrue(rendered.contains("░"));
29+
assertFalse(rendered.contains("█"));
30+
assertEquals(7, rendered.length());
31+
}
32+
33+
@Test
34+
void testRenderHalfProgress() {
35+
ProgressBar bar = ProgressBar.builder()
36+
.length(4)
37+
.build();
38+
String rendered = bar.render(0.5);
39+
40+
assertTrue(rendered.contains("█"));
41+
assertTrue(rendered.contains("░"));
42+
assertEquals(6, rendered.length());
43+
}
44+
45+
@Test
46+
void testRenderIntOverMax() {
47+
ProgressBar bar = ProgressBar.builder()
48+
.length(3)
49+
.build();
50+
String rendered = bar.render(5, 3);
51+
52+
assertEquals("[███]", rendered);
53+
}
54+
55+
@Test
56+
void testRenderIntWithZeroMax() {
57+
ProgressBar bar = ProgressBar.builder()
58+
.length(3)
59+
.build();
60+
String rendered = bar.render(0, 0);
61+
62+
assertEquals("[███]", rendered);
63+
}
64+
65+
@Test
66+
void testHideBrackets() {
67+
ProgressBar bar = ProgressBar.builder()
68+
.length(3)
69+
.hideBrackets()
70+
.build();
71+
String rendered = bar.render(1.0);
72+
73+
assertEquals("███", rendered);
74+
}
75+
76+
@Test
77+
void testCustomCharacters() {
78+
ProgressBar bar = ProgressBar.builder()
79+
.length(4)
80+
.filledChar("#")
81+
.emptyChar("-")
82+
.brackets("{", "}")
83+
.build();
84+
85+
String rendered = bar.render(0.5);
86+
assertEquals("{##--}", rendered);
87+
}
88+
89+
@Test
90+
void testNegativeProgressClampedToZero() {
91+
ProgressBar bar = ProgressBar.builder()
92+
.length(3)
93+
.build();
94+
String rendered = bar.render(-1.0);
95+
96+
assertEquals("[░░░]", rendered);
97+
}
98+
99+
@Test
100+
void testProgressGreaterThanOneClampedToOne() {
101+
ProgressBar bar = ProgressBar.builder()
102+
.length(3)
103+
.build();
104+
String rendered = bar.render(2.0);
105+
106+
assertEquals("[███]", rendered);
107+
}
108+
109+
@Test
110+
void testInvalidLengthThrowsException() {
111+
assertThrows(IllegalArgumentException.class, () -> ProgressBar.builder().length(0));
112+
assertThrows(IllegalArgumentException.class, () -> ProgressBar.builder().length(-5));
113+
}
114+
}

0 commit comments

Comments
 (0)