Skip to content

Commit f5a6ff8

Browse files
committed
fixed requested changes
1 parent f5aa49f commit f5a6ff8

8 files changed

Lines changed: 332 additions & 198 deletions

File tree

‎src/main/java/net/discordjug/javabot/systems/help/commands/HelpStatisticsSubcommand.java‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.ByteArrayOutputStream;
66
import java.io.IOException;
77
import java.time.LocalDate;
8+
import java.time.format.TextStyle;
89
import java.util.*;
910
import java.util.Map.Entry;
1011

@@ -45,7 +46,7 @@ public class HelpStatisticsSubcommand extends SlashCommand.Subcommand {
4546
public HelpStatisticsSubcommand(HelpTransactionRepository transactionRepository) {
4647
this.transactionRepository = transactionRepository;
4748
setCommandData(new SubcommandData("stats", "Shows an general plot about help activity in this server")
48-
.addOption(OptionType.BOOLEAN, "darkmode", "generate a plot in dark mode.", false)
49+
.addOption(OptionType.BOOLEAN, "darkmode", "Generates the plot with a dark background.", false)
4950
);
5051

5152
}
@@ -78,7 +79,7 @@ public void execute(SlashCommandInteractionEvent event) {
7879
correctMonth = false;
7980
}
8081
}
81-
plotData.add(new Pair<>(position.getMonth() + " " + position.getYear(), new Plotter.Bar(entriesForThisMonth)));
82+
plotData.add(new Pair<>(position.getMonth().getDisplayName(TextStyle.SHORT_STANDALONE, Locale.ROOT) + " '" + String.valueOf(position.getYear()).substring(2), new Plotter.Bar(entriesForThisMonth)));
8283
}
8384

8485
BufferedImage plot = new Plotter(plotData, "Help Statistics","Monthly assistance provided to community members",darkMode).plot();

‎src/main/java/net/discordjug/javabot/util/Plotter.java‎

Lines changed: 158 additions & 140 deletions
Large diffs are not rendered by default.

‎src/test/java/net/discordjug/javabot/util/PlotterTest.java‎

Lines changed: 171 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,86 +5,201 @@
55
import javax.imageio.ImageIO;
66
import java.awt.*;
77
import java.awt.image.BufferedImage;
8-
import java.io.File;
8+
import java.io.ByteArrayOutputStream;
99
import java.io.IOException;
10-
import java.time.YearMonth;
11-
import java.time.format.TextStyle;
12-
import java.util.ArrayList;
10+
import java.net.URL;
11+
import java.util.*;
1312
import java.util.List;
14-
import java.util.Locale;
15-
import java.util.Random;
1613

14+
import static org.junit.jupiter.api.Assertions.assertNotNull;
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
1716
import static org.junit.jupiter.api.Assertions.assertTrue;
1817

1918

2019
public class PlotterTest {
21-
private static final Color[] PALETTE = {
22-
new Color(0xF9C74F), new Color(0xF9506E), new Color(0x6C7280),
23-
new Color(0x5B8CFF), new Color(0x43D9AD), new Color(0xC084FC),
24-
new Color(0x22D3EE), new Color(0xFB923C)
25-
};
20+
@Test
21+
public void ImageDifferenceTest() throws IOException{
22+
List<Pair<String, Plotter.Bar>> testData = testData0();
23+
BufferedImage generatedImage = new Plotter(testData, "General helper statistics","subtitle").plot();
24+
BufferedImage expectedImage = readImage("PlotterTestImages/PlotterTest-Light.png");
25+
26+
assertTrue(assertImagesAreEqual(generatedImage,expectedImage));
27+
}
2628

2729
@Test
28-
public void ImageDifferenceTest(){
29-
List<Pair<String, Plotter.Bar>> testData = testData();
30-
BufferedImage img1 = new Plotter(testData, "General helper statistics","subtitle").plot();
31-
BufferedImage img2 = readImage("src/test/resources/PlotterTest.png");
30+
public void ImageDifferenceTestDarkMode() throws IOException{
31+
List<Pair<String, Plotter.Bar>> testData = testData0();
32+
BufferedImage generatedImage = new Plotter(testData, "General helper statistics","subtitle",true).plot();
33+
BufferedImage expectedImage = readImage("PlotterTestImages/PlotterTest-Dark.png");
3234

33-
assertTrue(compareImage(img1,img2));
35+
assertTrue(assertImagesAreEqual(generatedImage,expectedImage));
3436
}
3537

36-
public static BufferedImage readImage(String path){
37-
try {
38-
File inputFile = new File(path);
39-
BufferedImage image = ImageIO.read(inputFile);
40-
if (image == null) {
41-
throw new IOException("Image is null.");
42-
}
43-
return image;
44-
} catch (IOException e) {
45-
System.err.println("Error reading the image file: " + e.getMessage());
46-
return null;
47-
}
38+
@Test
39+
public void ImageDifferenceTestLessData() throws IOException{
40+
List<Pair<String, Plotter.Bar>> testData = testData1();
41+
BufferedImage generatedImage = new Plotter(testData, "General helper statistics","subtitle").plot();
42+
BufferedImage expectedImage = readImage("PlotterTestImages/PlotterTest-LessData.png");
43+
44+
assertTrue(assertImagesAreEqual(generatedImage,expectedImage));
4845
}
4946

50-
public static boolean compareImage(BufferedImage img1, BufferedImage img2) {
51-
if (img1 == null || img2 == null) {
52-
return false;
53-
}
47+
@Test
48+
public void ImageDifferenceTestNoData() throws IOException{
49+
List<Pair<String, Plotter.Bar>> testData = testData2();
50+
BufferedImage generatedImage = new Plotter(testData, "General helper statistics","subtitle").plot();
51+
BufferedImage expectedImage = readImage("PlotterTestImages/PlotterTest-NoData.png");
5452

55-
if (img1.getWidth() != img2.getWidth() ||
56-
img1.getHeight() != img2.getHeight()) {
57-
return false;
58-
}
53+
assertTrue(assertImagesAreEqual(generatedImage,expectedImage));
54+
}
55+
56+
private BufferedImage readImage(String fileName) throws IOException{
57+
URL resource = getClass().getClassLoader().getResource(fileName);
58+
BufferedImage image = ImageIO.read(resource);
59+
return image;
60+
}
61+
62+
public static boolean assertImagesAreEqual(BufferedImage actualImage, BufferedImage expectedImage) throws IOException {
63+
assertNotNull(actualImage, "Generated Image is Null.");
64+
assertNotNull(expectedImage, "Expected Image is Null.");
65+
66+
String actualImageBase64 = convertToBase64(actualImage);
5967

60-
for (int y = 0; y < img1.getHeight(); y++) {
61-
for (int x = 0; x < img1.getWidth(); x++) {
62-
if (img1.getRGB(x, y) != img2.getRGB(x, y)) {
63-
return false;
64-
}
68+
assertEquals(expectedImage.getWidth(), actualImage.getWidth(), "Image width does not match.\nActual image:"+actualImageBase64);
69+
assertEquals(expectedImage.getHeight(), actualImage.getHeight(), "Image height does not match.\nActual image:"+actualImageBase64);
70+
71+
for (int y = 0; y < actualImage.getHeight(); y++) {
72+
for (int x = 0; x < actualImage.getWidth(); x++) {
73+
assertEquals(actualImage.getRGB(x, y),expectedImage.getRGB(x, y),() -> "Image does not match.\nActual image:"+actualImageBase64);
6574
}
6675
}
6776
return true;
6877
}
6978

70-
private static List<Pair<String, Plotter.Bar>> testData() {
71-
Random random = new Random(42);
72-
List<Pair<String, Plotter.Bar>> entries = new ArrayList<>();
73-
YearMonth month = YearMonth.of(2026,9);
79+
private static String convertToBase64(BufferedImage image) throws IOException {
80+
ByteArrayOutputStream out = new ByteArrayOutputStream();
81+
ImageIO.write(image, "png", out);
82+
return Base64.getEncoder().encodeToString(out.toByteArray());
83+
}
7484

75-
for (int i = 0; i < 13; i++) {
76-
int segments = random.nextInt(3,5);
77-
List<Pair<Color, Double>> parts = new ArrayList<>();
85+
private static List<Pair<String, Plotter.Bar>> testData0() {
86+
Color yellow = new Color(249,199,79);
87+
Color red = new Color(249,80,110);
88+
Color grey = new Color(108,114,128);
89+
Color blue = new Color(91,140,255);
7890

79-
for (int s = 0; s < segments; s++) {
80-
double value = random.nextDouble(50,1800);
81-
parts.add(new Pair<>(PALETTE[s % PALETTE.length], value));
82-
}
91+
List<Pair<String, Plotter.Bar>> entries = Arrays.asList(
92+
new Pair<>("SEP '26", new Plotter.Bar(Arrays.asList(
93+
new Pair<>(yellow, 145.6),
94+
new Pair<>(red, 133.8),
95+
new Pair<>(grey, 1698.6),
96+
new Pair<>(blue, 1288.5)
97+
))),
98+
new Pair<>("OCT '26", new Plotter.Bar(Arrays.asList(
99+
new Pair<>(yellow, 1630.9),
100+
new Pair<>(red, 695.3),
101+
new Pair<>(grey, 532.5)
102+
))),
103+
new Pair<>("NOV '26", new Plotter.Bar(Arrays.asList(
104+
new Pair<>(yellow, 1383.6),
105+
new Pair<>(red, 1796.8),
106+
new Pair<>(grey, 315.9),
107+
new Pair<>(blue, 819.6)
108+
))),
109+
new Pair<>("DEC '2026", new Plotter.Bar(Arrays.asList(
110+
new Pair<>(yellow, 726.5),
111+
new Pair<>(red, 360.4),
112+
new Pair<>(grey, 1090.1)
113+
))),
114+
new Pair<>("JAN '27", new Plotter.Bar(Arrays.asList(
115+
new Pair<>(yellow, 488.6),
116+
new Pair<>(red, 689.0),
117+
new Pair<>(grey, 327.6),
118+
new Pair<>(blue, 529.8)
119+
))),
120+
new Pair<>("FEB '27", new Plotter.Bar(Arrays.asList(
121+
new Pair<>(yellow, 1049.3),
122+
new Pair<>(red, 1065.0),
123+
new Pair<>(grey, 1366.8)
124+
))),
125+
new Pair<>("MAR '27", new Plotter.Bar(Arrays.asList(
126+
new Pair<>(yellow, 603.9),
127+
new Pair<>(red, 398.4),
128+
new Pair<>(grey, 69.3),
129+
new Pair<>(blue, 1396.6)
130+
))),
131+
new Pair<>("APR '27", new Plotter.Bar(Arrays.asList(
132+
new Pair<>(yellow, 1298.4),
133+
new Pair<>(red, 891.0),
134+
new Pair<>(grey, 560.4)
135+
))),
136+
new Pair<>("MAY '27", new Plotter.Bar(Arrays.asList(
137+
new Pair<>(yellow, 1092.8),
138+
new Pair<>(red, 380.3),
139+
new Pair<>(grey, 712.2)
140+
))),
141+
new Pair<>("JUN '27", new Plotter.Bar(Arrays.asList(
142+
new Pair<>(yellow, 680.4),
143+
new Pair<>(red, 810.6),
144+
new Pair<>(grey, 850.3),
145+
new Pair<>(blue, 877.2)
146+
))),
147+
new Pair<>("JUL '27", new Plotter.Bar(Arrays.asList(
148+
new Pair<>(yellow, 1010.6),
149+
new Pair<>(red, 115.4),
150+
new Pair<>(grey, 142.0),
151+
new Pair<>(blue, 1430.0)
152+
))),
153+
new Pair<>("AUG '27", new Plotter.Bar(Arrays.asList(
154+
new Pair<>(yellow, 541.0),
155+
new Pair<>(red, 392.9),
156+
new Pair<>(grey, 363.7),
157+
new Pair<>(blue, 1564.9)
158+
))),
159+
new Pair<>("SEP '27", new Plotter.Bar(Arrays.asList(
160+
new Pair<>(yellow, 1009.2),
161+
new Pair<>(red, 64.2),
162+
new Pair<>(grey, 1375.8),
163+
new Pair<>(blue, 1154.3)
164+
)))
165+
);
166+
return entries;
167+
}
83168

84-
String monthLabel = month.getMonth().getDisplayName(TextStyle.FULL, Locale.ENGLISH).toUpperCase(Locale.ROOT) + " " + month.getYear();
85-
entries.add(new Pair<>(monthLabel, new Plotter.Bar(parts)));
86-
month = month.plusMonths(1);
87-
}
169+
private static List<Pair<String, Plotter.Bar>> testData1() {
170+
Color yellow = new Color(249,199,79);
171+
Color red = new Color(249,80,110);
172+
Color grey = new Color(108,114,128);
173+
Color blue = new Color(91,140,255);
174+
175+
List<Pair<String, Plotter.Bar>> entries = Arrays.asList(
176+
new Pair<>("SEP '26", new Plotter.Bar(Arrays.asList(
177+
new Pair<>(yellow, 145.6),
178+
new Pair<>(red, 133.8),
179+
new Pair<>(grey, 1698.6),
180+
new Pair<>(blue, 1288.5)
181+
))),
182+
new Pair<>("OCT '26", new Plotter.Bar(Arrays.asList(
183+
new Pair<>(yellow, 1630.9),
184+
new Pair<>(red, 695.3),
185+
new Pair<>(grey, 532.5)
186+
))),
187+
new Pair<>("NOV '26", new Plotter.Bar(Arrays.asList(
188+
new Pair<>(yellow, 1383.6),
189+
new Pair<>(red, 1796.8),
190+
new Pair<>(grey, 315.9),
191+
new Pair<>(blue, 819.6)
192+
))),
193+
new Pair<>("DEC '2026", new Plotter.Bar(Arrays.asList(
194+
new Pair<>(yellow, 726.5),
195+
new Pair<>(red, 360.4),
196+
new Pair<>(grey, 1090.1)
197+
)))
198+
);
88199
return entries;
89200
}
201+
202+
private static List<Pair<String, Plotter.Bar>> testData2() {
203+
return new ArrayList<Pair<String, Plotter.Bar>>();
204+
}
90205
}

‎src/test/resources/PlotterTest.png‎

-85.2 KB
Binary file not shown.
84.8 KB
Loading
47.3 KB
Loading
85.2 KB
Loading
21.6 KB
Loading

0 commit comments

Comments
 (0)