package cn.iocoder.yudao.module.qcreport.service.instance;
|
|
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.Test;
|
|
import java.time.LocalDate;
|
import java.util.Locale;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
/**
|
* 报告编号生成规则。
|
* <p>
|
* 这里守的是「编号一定能被自己读懂」:{@link ReportNoGenerator#nextSequence} 是对
|
* {@link ReportNoGenerator#format} 的逆运算,两者格式一旦对不上,
|
* 表现是流水号悄悄从 1 重来,然后撞唯一索引、重试 5 次后报「编号冲突」——
|
* 用户看到的是「出不了件」,很难联想到是编号格式的问题。
|
*/
|
class ReportNoGeneratorTest {
|
|
private static final LocalDate DAY = LocalDate.of(2026, 9, 18);
|
|
@Test
|
@DisplayName("前缀与编号格式")
|
void prefixAndFormat() {
|
assertEquals("QR20260918-", ReportNoGenerator.prefix(DAY));
|
assertEquals("QR20260918-0001", ReportNoGenerator.format(DAY, 1));
|
assertEquals("QR20260918-0042", ReportNoGenerator.format(DAY, 42));
|
assertEquals("QR20260918-9999", ReportNoGenerator.format(DAY, 9999));
|
}
|
|
@Test
|
@DisplayName("序号超过 9999 时位宽自然加宽,不截断也不回绕")
|
void formatWidensBeyondFourDigits() {
|
assertEquals("QR20260918-10000", ReportNoGenerator.format(DAY, 10_000));
|
assertEquals("QR20260918-100000", ReportNoGenerator.format(DAY, 100_000));
|
}
|
|
@Test
|
@DisplayName("编号里的数字与年份不受服务器 locale 影响")
|
void independentOfDefaultLocale() {
|
Locale original = Locale.getDefault();
|
try {
|
// 泰历会把 2026 年写成 2569;非拉丁数字字形会写出阿拉伯-印度数字
|
Locale.setDefault(Locale.forLanguageTag("th-TH-u-ca-buddhist-nu-thai"));
|
assertEquals("QR20260918-0007", ReportNoGenerator.format(DAY, 7));
|
} finally {
|
Locale.setDefault(original);
|
}
|
}
|
|
@Test
|
@DisplayName("同一天有编号时序号递增")
|
void nextSequenceIncrements() {
|
assertEquals(2, ReportNoGenerator.nextSequence("QR20260918-0001", DAY));
|
assertEquals(43, ReportNoGenerator.nextSequence("QR20260918-0042", DAY));
|
assertEquals(10_000, ReportNoGenerator.nextSequence("QR20260918-9999", DAY));
|
// 位宽加宽之后仍要能接着往下走
|
assertEquals(100_001, ReportNoGenerator.nextSequence("QR20260918-100000", DAY));
|
}
|
|
@Test
|
@DisplayName("还没有编号时从 1 开始")
|
void nextSequenceStartsAtOneWhenAbsent() {
|
assertEquals(1, ReportNoGenerator.nextSequence(null, DAY));
|
}
|
|
@Test
|
@DisplayName("拿到的编号属于别的日期时,按新的一天从 1 开始")
|
void nextSequenceResetsOnOtherDay() {
|
assertEquals(1, ReportNoGenerator.nextSequence("QR20260917-0042", DAY));
|
assertEquals(1, ReportNoGenerator.nextSequence("QR20260919-0042", DAY));
|
}
|
|
@Test
|
@DisplayName("格式不认识的编号一律归 1,而不是抛异常或硬解析")
|
void nextSequenceFallsBackOnUnknownFormat() {
|
// 不是本生成器的前缀
|
assertEquals(1, ReportNoGenerator.nextSequence("QC-2026-0001", DAY));
|
// 尾部不是数字
|
assertEquals(1, ReportNoGenerator.nextSequence("QR20260918-ABCD", DAY));
|
// 尾部混了数字与字母
|
assertEquals(1, ReportNoGenerator.nextSequence("QR20260918-00A1", DAY));
|
// 位数不足 4 位
|
assertEquals(1, ReportNoGenerator.nextSequence("QR20260918-1", DAY));
|
// 位数超过上限(本生成器产出不了这么长的尾巴,说明不是它写的)
|
assertEquals(1, ReportNoGenerator.nextSequence("QR20260918-1234567890", DAY));
|
// 只有前缀、没有流水
|
assertEquals(1, ReportNoGenerator.nextSequence("QR20260918-", DAY));
|
// 空串
|
assertEquals(1, ReportNoGenerator.nextSequence("", DAY));
|
}
|
|
}
|