xyc
4 天以前 922823a3f1faaf0293256e3ffb1285eaeb8a3b23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.trafficaudit.holiday.service;
 
import com.trafficaudit.holiday.service.HolidayStatService.DailyMetrics;
import org.junit.jupiter.api.Test;
 
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.function.Function;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
 
class HolidayBulletinServiceTest {
 
    @Test
    void formatsTableRatiosAsSignedPercentages() throws Exception {
        HolidayBulletinService service = new HolidayBulletinService(null);
 
        assertEquals("-4.7%", ratio(service, "95.3", "100", 1));
        assertEquals("-4.4%", ratio(service, "95.551398", "100", 1));
        assertEquals("-4.5%", ratio(service, "95.551398", "100", 2));
        assertEquals("-0.1%", ratio(service, "99.955", "100", 2));
        assertEquals("0%", ratio(service, "99.955", "100", 1));
        assertEquals("1.0%", ratio(service, "101", "100", 1));
        assertEquals("0%", ratio(service, "100", "100", 1));
        assertEquals("0%", ratio(service, "10004", "10000", 1));
        assertEquals("—", ratio(service, "100", null, 1));
        assertEquals("—", ratio(service, "100", "0", 1));
    }
 
    @Test
    void comparesCivilAviationOnlyThroughCoveredDay() throws Exception {
        HolidayStatService stat = mock(HolidayStatService.class);
        HolidayBulletinService service = new HolidayBulletinService(stat);
 
        DailyMetrics current = new DailyMetrics();
        current.setYear(2026);
        current.setHolidayType("NATIONAL_DAY");
        current.setDayIndex(2);
 
        DailyMetrics coveredDay = new DailyMetrics();
        coveredDay.setCivilAviation(new BigDecimal("6.7482"));
        DailyMetrics missingDay = new DailyMetrics();
 
        when(stat.dailyMetrics(2026, "NATIONAL_DAY", 2)).thenReturn(missingDay);
        when(stat.dailyMetrics(2026, "NATIONAL_DAY", 1)).thenReturn(coveredDay);
 
        DailyMetrics previousYear = new DailyMetrics();
        previousYear.setYear(2025);
        DailyMetrics previousYearThroughDay1 = new DailyMetrics();
        previousYearThroughDay1.setCivilAviation(new BigDecimal("7.5003"));
        when(stat.cumulativeMetrics(2025, "NATIONAL_DAY", 1)).thenReturn(previousYearThroughDay1);
 
        Object result = comparableCumulative(service, current, previousYear, DailyMetrics::getCivilAviation);
 
        assertSame(previousYearThroughDay1, result);
        verify(stat).cumulativeMetrics(2025, "NATIONAL_DAY", 1);
        verify(stat, never()).cumulativeMetrics(2025, "NATIONAL_DAY", 2);
    }
 
    @Test
    void comparableCumulativeIsNullWhenCurrentYearHasNoMetricData() throws Exception {
        HolidayStatService stat = mock(HolidayStatService.class);
        HolidayBulletinService service = new HolidayBulletinService(stat);
 
        DailyMetrics current = new DailyMetrics();
        current.setYear(2026);
        current.setHolidayType("NATIONAL_DAY");
        current.setDayIndex(2);
        when(stat.dailyMetrics(2026, "NATIONAL_DAY", 2)).thenReturn(new DailyMetrics());
        when(stat.dailyMetrics(2026, "NATIONAL_DAY", 1)).thenReturn(new DailyMetrics());
 
        Object result = comparableCumulative(service, current, new DailyMetrics(), DailyMetrics::getCivilAviation);
 
        assertNull(result);
        verify(stat, never()).cumulativeMetrics(0, "NATIONAL_DAY", 1);
    }
 
    @Test
    void cumulativeParagraphUsesExcelDisplayThenBulletinRounding() throws Exception {
        HolidayBulletinService service = new HolidayBulletinService(null);
 
        DailyMetrics current = new DailyMetrics();
        current.setTotalPersonFlow(new BigDecimal("3088.62958"));
        DailyMetrics previousYear = new DailyMetrics();
        previousYear.setTotalPersonFlow(new BigDecimal("3232.42742"));
        DailyMetrics twoYearsAgo = new DailyMetrics();
        twoYearsAgo.setTotalPersonFlow(new BigDecimal("3137.80860"));
 
        Method method = HolidayBulletinService.class.getDeclaredMethod(
                "cumulativeParagraph", DailyMetrics.class, DailyMetrics.class, DailyMetrics.class);
        method.setAccessible(true);
        String text = (String) method.invoke(service, current, previousYear, twoYearsAgo);
 
        assertEquals(
                "假期以来,全省全社会跨区域人员流动量累计3088.63万人次,比2025年同期下降4.5%,比2024年同期下降1.6%。",
                text);
    }
 
    private Object comparableCumulative(HolidayBulletinService service, DailyMetrics current,
                                        DailyMetrics comparisonYear,
                                        Function<DailyMetrics, BigDecimal> selector) throws Exception {
        Method method = HolidayBulletinService.class.getDeclaredMethod(
                "comparableCumulative", DailyMetrics.class, DailyMetrics.class, Function.class);
        method.setAccessible(true);
        return method.invoke(service, current, comparisonYear, selector);
    }
 
    private String ratio(HolidayBulletinService service, String current, String base,
                         int excelPercentScale) throws Exception {
        Method method = HolidayBulletinService.class.getDeclaredMethod(
                "ratio", BigDecimal.class, BigDecimal.class, int.class);
        method.setAccessible(true);
        BigDecimal currentValue = current == null ? null : new BigDecimal(current);
        BigDecimal baseValue = base == null ? null : new BigDecimal(base);
        return (String) method.invoke(service, currentValue, baseValue, excelPercentScale);
    }
}