Skip to content

Commit 2ec90a6

Browse files
committed
Add a simple progressBar
1 parent 482047f commit 2ec90a6

File tree

2 files changed

+266
-0
lines changed

2 files changed

+266
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
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+
for (int i = 0; i < this.length; i++) {
43+
if (i < filled) {
44+
bar.append(this.filledToken);
45+
}
46+
else {
47+
bar.append(this.emptyToken);
48+
}
49+
}
50+
51+
if (this.showBrackets) {
52+
bar.append(this.bracketColor).append(this.rightBracket);
53+
}
54+
55+
return bar.toString();
56+
}
57+
58+
public String render(int current, int max) {
59+
if (max <= 0) {
60+
return this.render(1.0);
61+
}
62+
double progress = (double) current / max;
63+
return this.render(progress);
64+
}
65+
66+
public String render(long current, long max) {
67+
if (max <= 0) {
68+
return this.render(1.0);
69+
}
70+
double progress = (double) current / max;
71+
return this.render(progress);
72+
}
73+
74+
public static Builder builder() {
75+
return new Builder();
76+
}
77+
78+
public static class Builder {
79+
private String filledChar = "█";
80+
private String emptyChar = "░";
81+
private String filledColor = "";
82+
private String emptyColor = "";
83+
private String leftBracket = "[";
84+
private String rightBracket = "]";
85+
private String bracketColor = "";
86+
private int length = 10;
87+
private boolean showBrackets = true;
88+
89+
public Builder filledChar(String filledChar) {
90+
this.filledChar = filledChar;
91+
return this;
92+
}
93+
94+
public Builder emptyChar(String emptyChar) {
95+
this.emptyChar = emptyChar;
96+
return this;
97+
}
98+
99+
public Builder filledColor(String filledColor) {
100+
this.filledColor = filledColor;
101+
return this;
102+
}
103+
104+
public Builder emptyColor(String emptyColor) {
105+
this.emptyColor = emptyColor;
106+
return this;
107+
}
108+
109+
public Builder leftBracket(String leftBracket) {
110+
this.leftBracket = leftBracket;
111+
return this;
112+
}
113+
114+
public Builder rightBracket(String rightBracket) {
115+
this.rightBracket = rightBracket;
116+
return this;
117+
}
118+
119+
public Builder brackets(String left, String right) {
120+
this.leftBracket = left;
121+
this.rightBracket = right;
122+
return this;
123+
}
124+
125+
public Builder bracketColor(String bracketColor) {
126+
this.bracketColor = bracketColor;
127+
return this;
128+
}
129+
130+
public Builder length(int length) {
131+
if (length <= 0) {
132+
throw new IllegalArgumentException("Length must be positive");
133+
}
134+
this.length = length;
135+
return this;
136+
}
137+
138+
public Builder showBrackets(boolean showBrackets) {
139+
this.showBrackets = showBrackets;
140+
return this;
141+
}
142+
143+
public Builder hideBrackets() {
144+
this.showBrackets = false;
145+
return this;
146+
}
147+
148+
public ProgressBar build() {
149+
return new ProgressBar(this);
150+
}
151+
}
152+
}
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)