| New file |
| | |
| | | package com.trafficaudit.holiday.service; |
| | | |
| | | import org.junit.jupiter.api.Test; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.math.BigDecimal; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.assertArrayEquals; |
| | | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | | import static org.junit.jupiter.api.Assertions.assertFalse; |
| | | import static org.junit.jupiter.api.Assertions.assertNotNull; |
| | | import static org.junit.jupiter.api.Assertions.assertTrue; |
| | | |
| | | class HolidayTrendChartServiceTest { |
| | | |
| | | @Test |
| | | void rendersLinePieAndStackedChartsAsPng() throws Exception { |
| | | HolidayTrendChartService service = new HolidayTrendChartService(); |
| | | HolidayTrendChartService.ChartSeries first = new HolidayTrendChartService.ChartSeries(); |
| | | first.setName("2026年"); |
| | | first.setValues(java.util.Arrays.asList( |
| | | java.math.BigDecimal.ONE, java.math.BigDecimal.TEN, null)); |
| | | HolidayTrendChartService.ChartSeries second = new HolidayTrendChartService.ChartSeries(); |
| | | second.setName("2025年"); |
| | | second.setValues(java.util.Arrays.asList( |
| | | java.math.BigDecimal.valueOf(2), java.math.BigDecimal.valueOf(8), |
| | | java.math.BigDecimal.valueOf(4))); |
| | | |
| | | byte[] line = service.lineChart("万人次", java.util.Arrays.asList(first, second), false); |
| | | assertPng(line); |
| | | assertNoLargeLightGrayBackground(line); |
| | | |
| | | HolidayTrendChartService.ChartCategory category = new HolidayTrendChartService.ChartCategory(); |
| | | category.setName("铁路"); |
| | | category.setValue(java.math.BigDecimal.TEN); |
| | | byte[] pie = service.pieChart("人次", java.util.Collections.singletonList(category), 400, 300); |
| | | assertPng(pie); |
| | | |
| | | byte[] stacked = service.stackedBarChart("占比", java.util.Arrays.asList("10月1日", "10月2日"), |
| | | java.util.Arrays.asList(first, second), true, 500, 320); |
| | | assertPng(stacked); |
| | | assertNoLargeLightGrayBackground(stacked); |
| | | } |
| | | |
| | | @Test |
| | | void roundsLineDataToTheSamePrecisionAsLabels() { |
| | | assertEquals(new BigDecimal("0.49"), |
| | | HolidayTrendChartService.displayValue(new BigDecimal("0.4904"), false, 2)); |
| | | assertEquals(new BigDecimal("0.49"), |
| | | HolidayTrendChartService.displayValue(new BigDecimal("0.4911"), false, 2)); |
| | | assertEquals(new BigDecimal("0.491"), |
| | | HolidayTrendChartService.displayValue(new BigDecimal("0.4911"), false, 3)); |
| | | assertEquals(new BigDecimal("0.123"), |
| | | HolidayTrendChartService.displayValue(new BigDecimal("0.1234"), true, 2)); |
| | | } |
| | | |
| | | @Test |
| | | void rendersSameGeometryWhenValuesRoundToSameLabel() { |
| | | HolidayTrendChartService service = new HolidayTrendChartService(); |
| | | HolidayTrendChartService.ChartSeries first = new HolidayTrendChartService.ChartSeries(); |
| | | first.setName("平均拥挤度"); |
| | | first.setValues(java.util.Arrays.asList( |
| | | new BigDecimal("0.4904"), new BigDecimal("0.4923"), new BigDecimal("0.5100"))); |
| | | HolidayTrendChartService.ChartSeries second = new HolidayTrendChartService.ChartSeries(); |
| | | second.setName("平均拥挤度"); |
| | | second.setValues(java.util.Arrays.asList( |
| | | new BigDecimal("0.4911"), new BigDecimal("0.4934"), new BigDecimal("0.5100"))); |
| | | |
| | | byte[] firstChart = service.lineChart("拥挤度", |
| | | java.util.Collections.singletonList(first), false, 2, 1100, 590); |
| | | byte[] secondChart = service.lineChart("拥挤度", |
| | | java.util.Collections.singletonList(second), false, 2, 1100, 590); |
| | | |
| | | assertPng(firstChart); |
| | | assertPng(secondChart); |
| | | assertArrayEquals(firstChart, secondChart); |
| | | } |
| | | |
| | | @Test |
| | | void scalesLineChartHeightForBetterVerticalSeparation() throws Exception { |
| | | HolidayTrendChartService service = new HolidayTrendChartService(); |
| | | HolidayTrendChartService.ChartSeries series = new HolidayTrendChartService.ChartSeries(); |
| | | series.setName("测试"); |
| | | series.setValues(java.util.Arrays.asList( |
| | | new BigDecimal("1.00"), new BigDecimal("2.00"), new BigDecimal("3.00"))); |
| | | |
| | | byte[] png = service.lineChart("万人次", |
| | | java.util.Collections.singletonList(series), false, 1100, 590); |
| | | BufferedImage image = ImageIO.read(new ByteArrayInputStream(png)); |
| | | |
| | | assertNotNull(image); |
| | | assertEquals(HolidayTrendChartService.scaleLineChartHeight(590), image.getHeight()); |
| | | } |
| | | |
| | | @Test |
| | | void rendersHigherPrecisionLineLabelsWhenRequested() { |
| | | HolidayTrendChartService service = new HolidayTrendChartService(); |
| | | HolidayTrendChartService.ChartSeries congestion = new HolidayTrendChartService.ChartSeries(); |
| | | congestion.setName("平均拥挤度"); |
| | | congestion.setValues(java.util.Arrays.asList( |
| | | new java.math.BigDecimal("0.467029"), |
| | | new java.math.BigDecimal("0.490890"), |
| | | new java.math.BigDecimal("0.492414"))); |
| | | |
| | | byte[] twoDecimals = service.lineChart("拥挤度", |
| | | java.util.Collections.singletonList(congestion), false, 2, 1100, 590); |
| | | byte[] threeDecimals = service.lineChart("拥挤度", |
| | | java.util.Collections.singletonList(congestion), false, 3, 1100, 590); |
| | | |
| | | assertPng(twoDecimals); |
| | | assertPng(threeDecimals); |
| | | assertFalse(java.util.Arrays.equals(twoDecimals, threeDecimals)); |
| | | } |
| | | |
| | | private void assertNoLargeLightGrayBackground(byte[] data) throws Exception { |
| | | BufferedImage image = ImageIO.read(new ByteArrayInputStream(data)); |
| | | int matches = 0; |
| | | for (int y = 0; y < image.getHeight(); y++) { |
| | | for (int x = 0; x < image.getWidth(); x++) { |
| | | int rgb = image.getRGB(x, y) & 0xFFFFFF; |
| | | if (rgb == 0xF3F4F3) matches++; |
| | | } |
| | | } |
| | | assertTrue(matches < image.getWidth() * image.getHeight() / 20, |
| | | "chart still contains a large light-gray background area"); |
| | | } |
| | | |
| | | private void assertPng(byte[] data) { |
| | | assertNotNull(data); |
| | | assertTrue(data.length > 100); |
| | | assertTrue(data[0] == (byte) 0x89 && data[1] == 0x50 |
| | | && data[2] == 0x4e && data[3] == 0x47); |
| | | } |
| | | } |