Commit eddd21f4e8287cd232b0fc07b2f1be8d6f83d840

Authored by haohao
1 parent 83ce168a

fix(infra): 修复 Windows 下 Codegen 单测

yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java
... ... @@ -457,8 +457,10 @@ public class CodegenEngine {
457 457 * @return 格式化后的代码
458 458 */
459 459 private String prettyCode(String content, String vmPath) {
460   - // Vue 界面:去除字段后面多余的 , 逗号,解决前端的 Pretty 代码格式检查的报错(内含换行归一化)
461   - content = CodegenFormatUtils.applyVueTrailingCommaFix(content, vmPath);
  460 + // Vue 界面:去除字段后面多余的 , 逗号,解决前端的 Pretty 代码格式检查的报错(需要排除 vben5、vue3_admin_uniapp)
  461 + if (!StrUtil.containsAny(vmPath, "vben5", "vue3_admin_uniapp")) {
  462 + content = content.replaceAll(",\\r?\\n}", "\n}").replaceAll(",\\r?\\n }", "\n }");
  463 + }
462 464 // Vue 界面:去除多的 dateFormatter,只有一个的情况下,说明没使用到
463 465 if (StrUtil.count(content, "dateFormatter") == 1) {
464 466 content = StrUtils.removeLineContains(content, "dateFormatter");
... ... @@ -480,7 +482,7 @@ public class CodegenEngine {
480 482 if (StrUtil.count(content, "DICT_TYPE.") == 0) {
481 483 content = StrUtils.removeLineContains(content, "DICT_TYPE");
482 484 }
483   - return CodegenFormatUtils.formatGeneratedContent(content);
  485 + return content;
484 486 }
485 487  
486 488 private Map<String, Object> initBindingMap(DbType dbType, CodegenTableDO table, List<CodegenColumnDO> columns,
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenFormatUtils.java deleted
1   -package cn.iocoder.yudao.module.infra.service.codegen.inner;
2   -
3   -import cn.hutool.core.util.StrUtil;
4   -
5   -/**
6   - * 代码生成结果格式化工具
7   - */
8   -final class CodegenFormatUtils {
9   -
10   - /**
11   - * 经典 Vue2 模板目录,与 {@link CodegenEngine#vueTemplatePath(String)} 一致
12   - */
13   - private static final String CLASSIC_VUE2_TEMPLATE_PREFIX = "codegen/vue/";
14   -
15   - /**
16   - * 经典 Vue3 模板目录,与 {@link CodegenEngine#vue3TemplatePath(String)} 一致。
17   - * 使用前缀 {@code codegen/vue3/} 而非子串匹配,避免误伤 {@code vue3_vben5}、{@code vue3_admin_uniapp} 等目录。
18   - */
19   - private static final String CLASSIC_VUE3_TEMPLATE_PREFIX = "codegen/vue3/";
20   -
21   - private CodegenFormatUtils() {
22   - }
23   -
24   - /**
25   - * 经典 Vue2 / Vue3 模板(Element UI / Element Plus 标准模版)
26   - */
27   - static boolean isClassicVueTemplate(String vmPath) {
28   - if (StrUtil.isEmpty(vmPath)) {
29   - return false;
30   - }
31   - return StrUtil.startWith(vmPath, CLASSIC_VUE2_TEMPLATE_PREFIX)
32   - || StrUtil.startWith(vmPath, CLASSIC_VUE3_TEMPLATE_PREFIX);
33   - }
34   -
35   - /**
36   - * 是否处理 {@code ,\n}} / {@code ,\n }} 形式的末尾逗号(经典 Vue + vue3_vben2;排除 vben5、uniapp)
37   - */
38   - static boolean needsVueTrailingCommaBeforeBraceFix(String vmPath) {
39   - if (StrUtil.containsAny(vmPath, "vben5", "vue3_admin_uniapp")) {
40   - return false;
41   - }
42   - return isClassicVueTemplate(vmPath) || StrUtil.startWith(vmPath, "codegen/vue3_vben/");
43   - }
44   -
45   - /**
46   - * 是否处理 {@code ,\n)} 形式的末尾逗号(仅经典 Vue 的 .vue 视图模板)
47   - */
48   - static boolean needsReactiveTrailingCommaFix(String vmPath) {
49   - return isClassicVueTemplate(vmPath) && StrUtil.endWith(vmPath, ".vue.vm");
50   - }
51   -
52   - /**
53   - * Vue 模板:统一去除对象/参数列表末尾多余逗号(与 {@link CodegenEngine#prettyCode} 历史行为一致)
54   - */
55   - static String applyVueTrailingCommaFix(String content, String vmPath) {
56   - if (content == null) {
57   - return null;
58   - }
59   - content = normalizeLineSeparators(content);
60   - if (needsVueTrailingCommaBeforeBraceFix(vmPath)) {
61   - content = content.replaceAll(",\\r?\\n}", "\n}")
62   - .replaceAll(",\\r?\\n }", "\n }");
63   - }
64   - if (needsReactiveTrailingCommaFix(vmPath)) {
65   - content = removeTrailingCommaBeforeCloseParen(content);
66   - }
67   - return content;
68   - }
69   -
70   - /**
71   - * 去除多行实参中 {@code ,\n)} 形式的末尾逗号(如 {@code foo(bar,\n)};{@code reactive} 的 {@code ,\n})} 由 {@code ,\n}} 规则处理)
72   - */
73   - static String removeTrailingCommaBeforeCloseParen(String content) {
74   - if (content == null) {
75   - return null;
76   - }
77   - return content.replaceAll(",\\r?\\n\\)", "\n)");
78   - }
79   -
80   - /**
81   - * 统一换行符为 LF
82   - */
83   - static String normalizeLineSeparators(String content) {
84   - if (content == null) {
85   - return null;
86   - }
87   - return content.replace("\r\n", "\n").replace('\r', '\n');
88   - }
89   -
90   - /**
91   - * 生产生成结果:LF + 保证文件以单个换行结尾(符合 POSIX / IDE 习惯)
92   - */
93   - static String formatGeneratedContent(String content) {
94   - content = normalizeLineSeparators(content);
95   - if (StrUtil.isEmpty(content)) {
96   - return content;
97   - }
98   - while (content.endsWith("\n\n")) {
99   - content = content.substring(0, content.length() - 1);
100   - }
101   - if (!content.endsWith("\n")) {
102   - content = content + "\n";
103   - }
104   - return content;
105   - }
106   -
107   - /**
108   - * 单测断言:LF + 去掉末尾空白(与历史 fixture 无尾换行对齐)
109   - */
110   - static String normalizeForAssert(String content) {
111   - if (content == null) {
112   - return null;
113   - }
114   - return normalizeLineSeparators(content).stripTrailing();
115   - }
116   -}
yudao-module-infra/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineAbstractTest.java
... ... @@ -18,7 +18,12 @@ import org.mockito.Spy;
18 18  
19 19 import java.io.ByteArrayInputStream;
20 20 import java.io.ByteArrayOutputStream;
21   -import java.util.*;
  21 +import java.util.ArrayList;
  22 +import java.util.HashMap;
  23 +import java.util.LinkedHashSet;
  24 +import java.util.List;
  25 +import java.util.Map;
  26 +import java.util.Set;
22 27  
23 28 import static org.junit.jupiter.api.Assertions.assertEquals;
24 29  
... ... @@ -99,17 +104,20 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
99 104 .map(m -> (String) m.get("filePath"))
100 105 .collect(java.util.stream.Collectors.toCollection(LinkedHashSet::new));
101 106 assertEquals(expectedFiles, result.keySet(), "生成文件集合不匹配");
102   - // 校验每个文件;归一化换行符,让断言不依赖文件落盘的换行风格
  107 + // 校验每个文件;归一化 \r\n 为 \n,让断言不依赖文件落盘的换行风格
103 108 asserts.forEach(assertMap -> {
104 109 String contentPath = (String) assertMap.get("contentPath");
105 110 String filePath = (String) assertMap.get("filePath");
106   - String expected = CodegenFormatUtils.normalizeForAssert(
107   - ResourceUtil.readUtf8Str("codegen/" + path + "/" + contentPath));
108   - String actual = CodegenFormatUtils.normalizeForAssert(result.get(filePath));
109   - assertEquals(expected, actual, filePath + ":不匹配");
  111 + String expected = normalizeLineEndings(ResourceUtil.readUtf8Str("codegen/" + path + "/" + contentPath));
  112 + String actual = result.get(filePath);
  113 + assertEquals(expected, normalizeLineEndings(actual), filePath + ":不匹配");
110 114 });
111 115 }
112 116  
  117 + private static String normalizeLineEndings(String content) {
  118 + return content == null ? null : content.replace("\r\n", "\n").replace("\r", "\n").stripTrailing();
  119 + }
  120 +
113 121 // ==================== 调试专用 ====================
114 122  
115 123 /**
... ... @@ -143,10 +151,10 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
143 151 + '/' + StrUtil.subBefore(lastFilePath, '.', true);
144 152 asserts.add(MapUtil.<String, String>builder().put("filePath", filePath)
145 153 .put("contentPath", contentPath).build());
146   - FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath);
  154 + FileUtil.writeUtf8String(normalizeLineEndings(fileContent), basePath + "/" + contentPath);
147 155 });
148 156 // 写入 assert.json 文件
149   - FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath + "/assert.json");
  157 + FileUtil.writeUtf8String(normalizeLineEndings(JsonUtils.toJsonPrettyString(asserts)), basePath + "/assert.json");
150 158 }
151 159  
152 160 }
... ...
yudao-module-infra/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenFormatUtilsTest.java deleted
1   -package cn.iocoder.yudao.module.infra.service.codegen.inner;
2   -
3   -import org.junit.jupiter.api.Test;
4   -
5   -import static org.junit.jupiter.api.Assertions.*;
6   -
7   -class CodegenFormatUtilsTest {
8   -
9   - @Test
10   - void testNormalizeLineSeparators() {
11   - assertEquals("a\nb", CodegenFormatUtils.normalizeLineSeparators("a\r\nb"));
12   - assertEquals("a\nb", CodegenFormatUtils.normalizeLineSeparators("a\rb"));
13   - }
14   -
15   - @Test
16   - void testFormatGeneratedContent() {
17   - assertEquals("class A {\n}\n", CodegenFormatUtils.formatGeneratedContent("class A {\r\n}\r\n"));
18   - assertEquals("x\n", CodegenFormatUtils.formatGeneratedContent("x"));
19   - assertEquals("x\n", CodegenFormatUtils.formatGeneratedContent("x\n\n\n"));
20   - assertEquals("", CodegenFormatUtils.formatGeneratedContent(""));
21   - assertEquals(" \n", CodegenFormatUtils.formatGeneratedContent(" "));
22   - }
23   -
24   - @Test
25   - void testNormalizeForAssert() {
26   - assertEquals("}", CodegenFormatUtils.normalizeForAssert("}\n"));
27   - assertEquals("a\nb", CodegenFormatUtils.normalizeForAssert("a\r\nb\r\n"));
28   - }
29   -
30   - @Test
31   - void testNormalizeForAssert_matchesFormatGeneratedContentForAssert() {
32   - String raw = "package demo;\r\n\r\npublic class A {\r\n private Long id;\r\n}\r\n";
33   - String generated = CodegenFormatUtils.formatGeneratedContent(raw);
34   - assertEquals(CodegenFormatUtils.normalizeForAssert(raw),
35   - CodegenFormatUtils.normalizeForAssert(generated));
36   - }
37   -
38   - @Test
39   - void testRemoveTrailingCommaBeforeCloseParen() {
40   - assertEquals("foo(bar\n)", CodegenFormatUtils.removeTrailingCommaBeforeCloseParen("foo(bar,\n)"));
41   - }
42   -
43   - @Test
44   - void testApplyVueTrailingCommaFix_classicVueReactive() {
45   - String input = "const queryParams = reactive({\n createTime: [],\n})\n";
46   - String expected = "const queryParams = reactive({\n createTime: []\n})\n";
47   - assertEquals(expected, CodegenFormatUtils.applyVueTrailingCommaFix(
48   - input, "codegen/vue3/views/index.vue.vm"));
49   - }
50   -
51   - @Test
52   - void testApplyVueTrailingCommaFix_skipVben5() {
53   - String input = "const x = {\n a: 1,\n}\n";
54   - assertEquals(input, CodegenFormatUtils.applyVueTrailingCommaFix(
55   - input, "codegen/vue3_vben5_antd/general/views/index.vue.vm"));
56   - }
57   -
58   - @Test
59   - void testIsClassicVueTemplate() {
60   - assertTrue(CodegenFormatUtils.isClassicVueTemplate("codegen/vue/views/index.vue.vm"));
61   - assertTrue(CodegenFormatUtils.isClassicVueTemplate("codegen/vue3/views/index.vue.vm"));
62   - assertTrue(CodegenFormatUtils.isClassicVueTemplate("codegen/vue3/api/api.ts.vm"));
63   - assertFalse(CodegenFormatUtils.isClassicVueTemplate("codegen/vue3_vben5_antd/schema/views/index.vue.vm"));
64   - assertFalse(CodegenFormatUtils.isClassicVueTemplate("codegen/vue3_vben/views/index.vue.vm"));
65   - assertFalse(CodegenFormatUtils.isClassicVueTemplate("codegen/vue3_admin_uniapp/views/index.vue.vm"));
66   - assertFalse(CodegenFormatUtils.isClassicVueTemplate("codegen/vue30/views/index.vue.vm")); // 非 codegen/vue3/ 前缀
67   - assertFalse(CodegenFormatUtils.isClassicVueTemplate("codegen/java/controller/controller.vm"));
68   - assertFalse(CodegenFormatUtils.isClassicVueTemplate(null));
69   - }
70   -
71   - @Test
72   - void testNeedsReactiveTrailingCommaFix() {
73   - assertTrue(CodegenFormatUtils.needsReactiveTrailingCommaFix("codegen/vue3/views/index.vue.vm"));
74   - assertFalse(CodegenFormatUtils.needsReactiveTrailingCommaFix("codegen/vue3/api/api.ts.vm"));
75   - assertFalse(CodegenFormatUtils.needsReactiveTrailingCommaFix("codegen/vue3_vben5_antd/general/views/index.vue.vm"));
76   - }
77   -
78   - @Test
79   - void testNeedsVueTrailingCommaBeforeBraceFix() {
80   - assertTrue(CodegenFormatUtils.needsVueTrailingCommaBeforeBraceFix("codegen/vue3/views/index.vue.vm"));
81   - assertTrue(CodegenFormatUtils.needsVueTrailingCommaBeforeBraceFix("codegen/vue3_vben/views/index.vue.vm"));
82   - assertFalse(CodegenFormatUtils.needsVueTrailingCommaBeforeBraceFix("codegen/vue3_vben5_antd/general/views/index.vue.vm"));
83   - assertFalse(CodegenFormatUtils.needsVueTrailingCommaBeforeBraceFix("codegen/vue3_admin_uniapp/views/index.vue.vm"));
84   - }
85   -}
86   -