scancscode 1.0.31 → 1.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.trae/specs/fix-doc-comment-boundary/checklist.md +7 -0
- package/.trae/specs/fix-doc-comment-boundary/spec.md +52 -0
- package/.trae/specs/fix-doc-comment-boundary/tasks.md +34 -0
- package/.trae/specs/fix-interpolated-string-nested-literals/checklist.md +7 -0
- package/.trae/specs/fix-interpolated-string-nested-literals/spec.md +55 -0
- package/.trae/specs/fix-interpolated-string-nested-literals/tasks.md +25 -0
- package/.trae/specs/fix-remaining-interpolated-string-index/checklist.md +9 -0
- package/.trae/specs/fix-remaining-interpolated-string-index/spec.md +59 -0
- package/.trae/specs/fix-remaining-interpolated-string-index/tasks.md +41 -0
- package/.trae/specs/fix-return-interpolated-string/checklist.md +8 -0
- package/.trae/specs/fix-return-interpolated-string/spec.md +60 -0
- package/.trae/specs/fix-return-interpolated-string/tasks.md +39 -0
- package/.trae/specs/handle-anonymous-function-strings/checklist.md +11 -0
- package/.trae/specs/handle-anonymous-function-strings/spec.md +137 -0
- package/.trae/specs/handle-anonymous-function-strings/tasks.md +65 -0
- package/.trae/specs/handle-interpolated-string-double-braces/checklist.md +9 -0
- package/.trae/specs/handle-interpolated-string-double-braces/spec.md +61 -0
- package/.trae/specs/handle-interpolated-string-double-braces/tasks.md +41 -0
- package/.trae/specs/handle-return-statement/checklist.md +11 -0
- package/.trae/specs/handle-return-statement/spec.md +76 -0
- package/.trae/specs/handle-return-statement/tasks.md +44 -0
- package/.trae/specs/handle-special-string-characters/checklist.md +13 -0
- package/.trae/specs/handle-special-string-characters/spec.md +94 -0
- package/.trae/specs/handle-special-string-characters/tasks.md +74 -0
- package/.trae/specs/unify-return-statement-string-extraction/checklist.md +10 -0
- package/.trae/specs/unify-return-statement-string-extraction/spec.md +70 -0
- package/.trae/specs/unify-return-statement-string-extraction/tasks.md +54 -0
- package/bin/scanliterals.js +3 -3
- package/bin/slimlangs.js +3 -3
- package/dist/debug-arg.js +30 -0
- package/dist/debug-args.js +34 -0
- package/dist/debug-comment-5.js +25 -0
- package/dist/debug-comment-strings.js +24 -0
- package/dist/debug-full.js +14 -0
- package/dist/debug-template-issue.js +33 -0
- package/dist/debug-test-5.js +23 -0
- package/dist/debug-test.js +21 -0
- package/dist/debug.js +15 -0
- package/dist/simple-debug.js +27 -0
- package/dist/simple-test.js +61 -0
- package/dist/src/CSharpStringExtractor.js +1791 -358
- package/dist/src/CmdExecutor.js +6 -8
- package/dist/temp-original-source.js +1 -0
- package/dist/test/CSharpStringExtractor.test.js +1587 -207
- package/dist/test-logic.js +79 -0
- package/dist/test-regex.js +13 -0
- package/docs/CSharpStringExtractor/344/273/243/347/240/201/347/224/237/346/210/220/346/217/220/347/244/272/350/257/215.txt +73 -0
- package/jest.config.js +9 -9
- package/package.json +1 -1
- package/src/CSCodeScanner.ts +305 -305
- package/src/CSVUtils.ts +181 -181
- package/src/CSharpStringExtractor.ts +2058 -479
- package/src/CmdExecutor.ts +107 -106
- package/src/LiteralCollector.ts +143 -143
- package/src/RunConvert.ts +3 -3
- package/src/RunSlimLangs.ts +3 -3
- package/src/TableScanner.ts +92 -92
- package/test/CSharpStringExtractor.test.ts +1673 -208
- package/test/KeeperDialog.cs +114 -0
- package/test/TestSpecialString.cs +24 -0
- package/tsconfig.json +109 -109
|
@@ -8,6 +8,7 @@ describe('CSharpStringExtractor', () => {
|
|
|
8
8
|
extractor = new CSharpStringExtractor();
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
+
// 测试从普通函数调用参数中提取字符串表达式信息, 只需要提取参数中的字符串值表达式, 不需要对提取的字符串表达式进行处理
|
|
11
12
|
test('should extract plain strings', () => {
|
|
12
13
|
const code = 'Console.WriteLine("Hello, world!");';
|
|
13
14
|
const snippets = extractor.extractStrings(code);
|
|
@@ -16,431 +17,502 @@ describe('CSharpStringExtractor', () => {
|
|
|
16
17
|
expect(snippets[0].literals).toEqual(['Hello, world!']);
|
|
17
18
|
});
|
|
18
19
|
|
|
20
|
+
// 已经追加 `.TR()` 后缀的字符串表达式不需要重复追加 `.TR()`
|
|
19
21
|
test('should handle strings with .TR() already appended', () => {
|
|
20
22
|
const code = 'obj.prop = "Hello, world!".TR();';
|
|
21
23
|
const snippets = extractor.extractStrings(code);
|
|
22
24
|
|
|
23
25
|
expect(snippets.length).toBe(1);
|
|
24
|
-
expect(snippets[0].originalCode).toBe('
|
|
25
|
-
expect(snippets[0].convertedCode).toBe('
|
|
26
|
+
expect(snippets[0].originalCode).toBe('"Hello, world!".TR()');
|
|
27
|
+
expect(snippets[0].convertedCode).toBe('"Hello, world!".TR()');
|
|
26
28
|
expect(snippets[0].isChanged).toBe(false);
|
|
27
29
|
});
|
|
28
30
|
|
|
31
|
+
// 测试从普通函数调用参数中提取字符串表达式信息, 只需要提取参数中的字符串值表达式, 不需要对提取的字符串表达式进行处理, 也不需要追加 `.TR()`
|
|
29
32
|
test('should not add .TR() to function arguments', () => {
|
|
30
33
|
const code = 'CallFunc("Hello, world!");';
|
|
31
34
|
const snippets = extractor.extractStrings(code);
|
|
32
35
|
|
|
33
36
|
expect(snippets.length).toBe(1);
|
|
34
|
-
expect(snippets[0].
|
|
37
|
+
expect(snippets[0].originalCode).toBe('"Hello, world!"');
|
|
38
|
+
expect(snippets[0].convertedCode).toBe('"Hello, world!"');
|
|
35
39
|
});
|
|
36
40
|
|
|
41
|
+
// 测试从普通属性赋值语句中提取字符串表达式信息, 只需要提取赋值表达式中的字符串值表达式, 不需要对提取的字符串表达式进行处理, 也不需要追加 `.TR()`
|
|
37
42
|
test('should not add .TR() to regular property assignments', () => {
|
|
38
43
|
const code = 'obj.prop = "Hello, world!";';
|
|
39
44
|
const snippets = extractor.extractStrings(code);
|
|
40
45
|
|
|
41
46
|
expect(snippets.length).toBe(1);
|
|
42
|
-
expect(snippets[0].
|
|
47
|
+
expect(snippets[0].originalCode).toBe('"Hello, world!"');
|
|
48
|
+
expect(snippets[0].convertedCode).toBe('"Hello, world!"');
|
|
43
49
|
});
|
|
44
50
|
|
|
51
|
+
// 测试从 $"" 字符串模板(也叫内插字符串)中提取字符串表达式信息, 需要先将字符串模板转换为 `string.Format(...)` 格式, 然后将 `string.Format(...)` 替换为 `Tr.Format(...)`, 之后从 `Tr.Format(...)` 的函数调用参数中提取普通字符串、或进一步递归提取字符串表达式信息
|
|
45
52
|
test('should handle $"" string templates', () => {
|
|
46
|
-
const code = '$"Hello, {name}!";';
|
|
53
|
+
const code = 'var label1 = $"Hello, {name}!";';
|
|
47
54
|
const snippets = extractor.extractStrings(code);
|
|
48
55
|
|
|
49
56
|
expect(snippets.length).toBe(1);
|
|
57
|
+
expect(snippets[0].originalCode).toBe('$"Hello, {name}!"');
|
|
50
58
|
expect(snippets[0].literals).toContain('Hello, {0}!');
|
|
51
|
-
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, {0}!", name)
|
|
59
|
+
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
52
60
|
});
|
|
53
61
|
|
|
62
|
+
// 测试从普通函数调用参数中提取 $"" 字符串模板(也叫内插字符串), 需要先将字符串模板转换为 `string.Format(...)` 格式, 然后将 `string.Format(...)` 替换为 `Tr.Format(...)`, 之后从 `Tr.Format(...)` 的函数调用参数中提取普通字符串、或进一步递归提取字符串表达式信息
|
|
54
63
|
test('should handle $"" string templates in function calls', () => {
|
|
55
64
|
const code = 'CallFunc($"Hello, world: {obj.Func1()}");';
|
|
56
65
|
const snippets = extractor.extractStrings(code);
|
|
57
66
|
|
|
58
67
|
expect(snippets.length).toBe(1);
|
|
59
|
-
expect(snippets[0].
|
|
68
|
+
expect(snippets[0].originalCode).toBe('$"Hello, world: {obj.Func1()}"');
|
|
69
|
+
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, world: {0}", obj.Func1())');
|
|
60
70
|
});
|
|
61
71
|
|
|
72
|
+
// 测试遇到 `string.Format(...)` 形式的字符串表达式, 需要先将 `string.Format(...)` 替换为 `Tr.Format(...)`, 之后从 `Tr.Format(...)` 的函数调用参数中提取普通字符串、或进一步递归提取字符串表达式信息, 内插字符串概念参考: `https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/tokens/interpolated`
|
|
62
73
|
test('should convert string.Format to Tr.Format', () => {
|
|
63
74
|
const code = 'string.Format("Hello, ", name, "!");';
|
|
64
75
|
const snippets = extractor.extractStrings(code);
|
|
65
76
|
|
|
66
77
|
expect(snippets.length).toBe(1);
|
|
67
|
-
|
|
78
|
+
// string.Format(...) 形式的字符串表达式, 不需要对提取的字符串表达式进行处理, 也不需要追加 `.TR()`
|
|
79
|
+
// string.Format(...) 形式包含的字符串表达式, 需要特殊处理, 连带 `string.Format()` 一起捕获存入 originalCode 成员
|
|
80
|
+
expect(snippets[0].originalCode).toBe('string.Format("Hello, ", name, "!")');
|
|
81
|
+
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, ", name, "!")');
|
|
68
82
|
});
|
|
69
83
|
|
|
84
|
+
// 测试遇到 `string.Format(...)` 形式的字符串表达式, 需要先将 `string.Format(...)` 替换为 `Tr.Format(...)`, 之后从 `Tr.Format(...)` 的函数调用参数中提取普通字符串、或进一步递归提取字符串表达式信息
|
|
85
|
+
// 同时测试用 `+` 连接的字符串表达式, 确保用 `+` 符号拼接的字符串表达式被整体处理, 从中提取字符串表达式信息, 而不是分别处理 `+` 两边每个字符串表达式
|
|
70
86
|
test('should handle string.Format in .text assignments', () => {
|
|
71
87
|
const code = 'label.text = Tr.Format("pre", Func(), "sub") + other;';
|
|
72
88
|
const snippets = extractor.extractStrings(code);
|
|
73
89
|
|
|
74
90
|
expect(snippets.length).toBe(1);
|
|
91
|
+
expect(snippets[0].originalCode).toBe('Tr.Format("pre", Func(), "sub") + other');
|
|
75
92
|
expect(snippets[0].literals).toContain('pre');
|
|
76
93
|
expect(snippets[0].literals).toContain('sub');
|
|
77
94
|
});
|
|
78
95
|
|
|
96
|
+
// 测试用 `+` 连接的字符串表达式, 确保用 `+` 符号拼接的字符串表达式被整体处理, 从中提取字符串表达式信息, 而不是分别处理 `+` 两边每个字符串表达式; 并且给 `+` 连接的每个成分追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式
|
|
79
97
|
test('should handle string concatenation', () => {
|
|
80
|
-
const code = '"Hello, " + name + "!";';
|
|
98
|
+
const code = 'var label2 = "Hello, " + name + "!";';
|
|
81
99
|
const snippets = extractor.extractStrings(code);
|
|
82
100
|
|
|
83
101
|
expect(snippets.length).toBe(1);
|
|
84
|
-
expect(snippets[0].
|
|
102
|
+
expect(snippets[0].originalCode).toBe('"Hello, " + name + "!"');
|
|
103
|
+
expect(snippets[0].convertedCode).toBe('"Hello, ".TR() + name.TR() + "!".TR()');
|
|
85
104
|
});
|
|
86
105
|
|
|
106
|
+
// 测试 `xxx.text = yyy` 形式的赋值语句, 确保将 `yyy` 中的字符串表达式信息提取出来, 并追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式; 其中 `xxx`和`yyy` 代表某段C#字面量, 可以是对象、字符串、或其他表达式
|
|
87
107
|
test('should handle .text = assignments with function calls', () => {
|
|
88
108
|
const code = 'label.text = Func();';
|
|
89
109
|
const snippets = extractor.extractStrings(code);
|
|
90
110
|
|
|
91
111
|
expect(snippets.length).toBe(1);
|
|
92
|
-
expect(snippets[0].
|
|
112
|
+
expect(snippets[0].originalCode).toBe('Func()');
|
|
113
|
+
expect(snippets[0].convertedCode).toBe('Func().TR()');
|
|
93
114
|
});
|
|
94
115
|
|
|
116
|
+
// 测试 `xxx.text = xxx + xxx` 形式的赋值语句, 确保将 `xxx.text` 中的 `xxx` 字符串表达式提取出来, 并追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式; 其中 `xxx`和`yyy` 代表某段C#表达式, 可以是对象、字符串、或其他表达式
|
|
95
117
|
test('should handle .text = assignments with multiple function calls', () => {
|
|
96
118
|
const code = 'label.text = Func() + Func();';
|
|
97
119
|
const snippets = extractor.extractStrings(code);
|
|
98
120
|
|
|
99
121
|
expect(snippets.length).toBe(1);
|
|
100
|
-
expect(snippets[0].
|
|
122
|
+
expect(snippets[0].originalCode).toBe('Func() + Func()');
|
|
123
|
+
expect(snippets[0].convertedCode).toBe('Func().TR() + Func().TR()');
|
|
101
124
|
});
|
|
102
125
|
|
|
126
|
+
// 测试 `xxx.text = yyy` 形式的赋值语句, 确保将 `yyy` 中的 `xxx` 内插字符串提取出来, 并转换为 `Tr.Format(...)` 形式; 其中 `xxx`和`yyy` 代表某段C#表达式, 可以是对象、字符串、或其他表达式
|
|
103
127
|
test('should handle .text = assignments with string templates', () => {
|
|
104
128
|
const code = 'label.text = $"pre{Func()}sub";';
|
|
105
129
|
const snippets = extractor.extractStrings(code);
|
|
106
130
|
|
|
107
131
|
expect(snippets.length).toBe(1);
|
|
132
|
+
expect(snippets[0].originalCode).toBe('$"pre{Func()}sub"');
|
|
108
133
|
expect(snippets[0].literals).toContain('pre{0}sub');
|
|
109
|
-
expect(snippets[0].convertedCode).toBe('
|
|
134
|
+
expect(snippets[0].convertedCode).toBe('Tr.Format("pre{0}sub", Func())');
|
|
110
135
|
});
|
|
111
136
|
|
|
137
|
+
// 测试从内插字符串中提取字符串表达式信息时, 需要注意转换和捕获内插字符串格式参数, 内插字符串和对应格式参数参考: `https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/tokens/interpolated`
|
|
112
138
|
test('should handle .text = assignments with string.Format', () => {
|
|
113
139
|
const code = 'label.text = string.Format("pre{0:F2}{1}", Func(), "sub") + other;';
|
|
114
140
|
const snippets = extractor.extractStrings(code);
|
|
115
141
|
|
|
116
142
|
expect(snippets.length).toBe(1);
|
|
143
|
+
expect(snippets[0].originalCode).toBe('string.Format("pre{0:F2}{1}", Func(), "sub") + other');
|
|
117
144
|
expect(snippets[0].literals).toContain('pre{0:F2}{1}');
|
|
118
145
|
expect(snippets[0].literals).toContain('sub');
|
|
119
146
|
});
|
|
120
147
|
|
|
148
|
+
// 测试用 `+` 连接的字符串表达式, 确保用 `+` 符号拼接的字符串表达式被整体处理, 从中提取字符串表达式信息, 而不是分别处理 `+` 两边每个字符串表达式; 并且给 `+` 连接的每个成分追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式或进一步递归处理
|
|
121
149
|
test('should handle complex concatenation with existing .TR() calls', () => {
|
|
122
|
-
const code = '"Hello, ".TR() + name.TR() + obj2.name.TR() + obj2.nam1_e.Fn1().Prop + "!";';
|
|
150
|
+
const code = 'var hello3 = "Hello, ".TR() + name.TR() + obj2.name.TR() + obj2.nam1_e.Fn1().Prop + "!";';
|
|
123
151
|
const snippets = extractor.extractStrings(code);
|
|
124
152
|
|
|
125
153
|
expect(snippets.length).toBe(1);
|
|
126
|
-
expect(snippets[0].
|
|
154
|
+
expect(snippets[0].originalCode).toBe('"Hello, ".TR() + name.TR() + obj2.name.TR() + obj2.nam1_e.Fn1().Prop + "!"');
|
|
155
|
+
expect(snippets[0].convertedCode).toBe('"Hello, ".TR() + name.TR() + obj2.name.TR() + obj2.nam1_e.Fn1().Prop.TR() + "!".TR()');
|
|
127
156
|
});
|
|
128
157
|
|
|
158
|
+
// 测试处理包含转义引号的字符串表达式, 确保能正确提取和转换转义引号, 而不会影响字符串边界的正常解析
|
|
129
159
|
test('should handle escaped quotes in strings', () => {
|
|
130
|
-
const code = 'Debug.Log("aaa\\\"bbb\\\"c\\\"d
|
|
160
|
+
const code = 'Debug.Log("aaa\\\"bbb\\\"c\\\"d\\\\\\"cc");';
|
|
131
161
|
const snippets = extractor.extractStrings(code);
|
|
132
162
|
|
|
133
163
|
expect(snippets.length).toBe(1);
|
|
164
|
+
expect(snippets[0].originalCode).toBe('"aaa\\\"bbb\\\"c\\\"d\\\\\\"cc"');
|
|
165
|
+
expect(snippets[0].convertedCode).toBe('"aaa\\\"bbb\\\"c\\\"d\\\\\\"cc"');
|
|
134
166
|
// 由于JavaScript字符串转义的复杂性,我们只检查是否提取了字符串
|
|
135
|
-
expect(snippets[0].literals
|
|
167
|
+
expect(snippets[0].literals).toEqual(['aaa\\\"bbb\\\"c\\\"d\\\\\\"cc']);
|
|
136
168
|
});
|
|
137
169
|
|
|
170
|
+
// 测试处理包含 `+` 连接的字符串表达式, 需要给 `+` 连接的每个成分追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式或进一步递归处理
|
|
138
171
|
test('should capture statement boundaries correctly', () => {
|
|
139
172
|
const code = 'obj.text = "Test property" + "Test property2";';
|
|
140
173
|
const snippets = extractor.extractStrings(code);
|
|
141
174
|
|
|
142
175
|
expect(snippets.length).toBe(1);
|
|
143
|
-
expect(snippets[0].originalCode).toBe('
|
|
176
|
+
expect(snippets[0].originalCode).toBe('"Test property" + "Test property2"');
|
|
177
|
+
expect(snippets[0].convertedCode).toBe('"Test property".TR() + "Test property2".TR()');
|
|
144
178
|
});
|
|
145
179
|
|
|
180
|
+
// 测试处理包含多个语句的C#代码, 确保能从各个语句中正确提取和转换每个语句中的字符串表达式, 而不会影响其他语句的正常解析
|
|
146
181
|
test('should handle multiple statements', () => {
|
|
147
182
|
const code = 'obj1.text = "Hello"; obj2.text = "World";';
|
|
148
183
|
const snippets = extractor.extractStrings(code);
|
|
149
184
|
|
|
150
185
|
expect(snippets.length).toBe(2);
|
|
151
|
-
expect(snippets[0].originalCode).toBe('
|
|
152
|
-
expect(snippets[
|
|
186
|
+
expect(snippets[0].originalCode).toBe('"Hello"');
|
|
187
|
+
expect(snippets[0].convertedCode).toBe('"Hello".TR()');
|
|
188
|
+
expect(snippets[1].originalCode).toBe('"World"');
|
|
189
|
+
expect(snippets[1].convertedCode).toBe('"World".TR()');
|
|
153
190
|
});
|
|
154
191
|
|
|
192
|
+
// 测试处理作为函数参数的内插字符串表达式, 确保能从内插字符串中提取字符串表达式信息, 并转换为 `Tr.Format(...)` 形式
|
|
155
193
|
test('should extract and convert string templates', () => {
|
|
156
194
|
const code = 'Ljk.Ilk($"Hello, {name}!");';
|
|
157
195
|
const snippets = extractor.extractStrings(code);
|
|
158
196
|
|
|
159
197
|
expect(snippets.length).toBeGreaterThan(0);
|
|
160
198
|
const snippet = snippets[0];
|
|
161
|
-
expect(snippet.originalCode).toBe('
|
|
162
|
-
expect(snippet.convertedCode).toBe('
|
|
199
|
+
expect(snippet.originalCode).toBe('$"Hello, {name}!"');
|
|
200
|
+
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
163
201
|
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
164
202
|
expect(snippet.isChanged).toBe(true);
|
|
165
203
|
});
|
|
166
204
|
|
|
205
|
+
// 测试处理 `string.Format` 调用, 确保能将其转换为 `Tr.Format(...)` 形式, 并正确提取字符串表达式信息
|
|
167
206
|
test('should convert string.Format to Tr.Format', () => {
|
|
168
207
|
const code = 'string.Format("Hello, {0}!", name);';
|
|
169
208
|
const snippets = extractor.extractStrings(code);
|
|
170
209
|
|
|
171
210
|
expect(snippets.length).toBeGreaterThan(0);
|
|
172
211
|
const snippet = snippets[0];
|
|
173
|
-
expect(snippet.originalCode).toBe('string.Format("Hello, {0}!", name)
|
|
174
|
-
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)
|
|
212
|
+
expect(snippet.originalCode).toBe('string.Format("Hello, {0}!", name)');
|
|
213
|
+
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
175
214
|
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
176
215
|
expect(snippet.isChanged).toBe(true);
|
|
177
216
|
});
|
|
178
217
|
|
|
218
|
+
// 测试处理 `xxx.text = yyy` 形式赋值语句, 以 `.text =` 给 `text` 成员赋值的表达式中, `yyy` 部分必定是字符串表达式, 需要从 `yyy` 中正确提取字符串表达式信息, 并给普通字符串表达式追加 `.TR()` 或者让内插字符串转换为 `Tr.Format(...)` 形式
|
|
179
219
|
test('should handle .text = assignments', () => {
|
|
180
220
|
const code = 'label.text = "Test";';
|
|
181
221
|
const snippets = extractor.extractStrings(code);
|
|
182
222
|
|
|
183
223
|
expect(snippets.length).toBeGreaterThan(0);
|
|
184
224
|
const snippet = snippets[0];
|
|
185
|
-
expect(snippet.originalCode).toBe('
|
|
186
|
-
expect(snippet.convertedCode).toBe('
|
|
225
|
+
expect(snippet.originalCode).toBe('"Test"');
|
|
226
|
+
expect(snippet.convertedCode).toBe('"Test".TR()');
|
|
187
227
|
expect(snippet.literals).toEqual(['Test']);
|
|
188
228
|
expect(snippet.isChanged).toBe(true);
|
|
189
229
|
});
|
|
190
230
|
|
|
231
|
+
// 测试处理包含 `+` 连接的字符串表达式, 需要给 `+` 连接的每个成分追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式或进一步递归处理
|
|
191
232
|
test('should handle string concatenations', () => {
|
|
192
|
-
const code = '"Hello, " + name + "!";';
|
|
233
|
+
const code = 'var wkleee = "Hello, " + name + "!";';
|
|
193
234
|
const snippets = extractor.extractStrings(code);
|
|
194
235
|
|
|
195
236
|
expect(snippets.length).toBeGreaterThan(0);
|
|
196
237
|
const snippet = snippets[0];
|
|
197
|
-
expect(snippet.originalCode).toBe('"Hello, " + name + "!"
|
|
198
|
-
expect(snippet.convertedCode).toBe('"Hello, ".TR() + name.TR() + "!".TR()
|
|
238
|
+
expect(snippet.originalCode).toBe('"Hello, " + name + "!"');
|
|
239
|
+
expect(snippet.convertedCode).toBe('"Hello, ".TR() + name.TR() + "!".TR()');
|
|
199
240
|
expect(snippet.literals).toEqual(['Hello, ', '!']);
|
|
200
241
|
expect(snippet.isChanged).toBe(true);
|
|
201
242
|
});
|
|
202
243
|
|
|
244
|
+
// 测试处理 `+` 连接的字符串表达式时, 确保不会给已经包含 `.TR()` 的字符串表达式再次追加 `.TR()`
|
|
203
245
|
test('should not add .TR() to strings already having it', () => {
|
|
204
|
-
const code = '"Hello".TR();';
|
|
246
|
+
const code = 'var wkle = "Hello".TR();';
|
|
205
247
|
const snippets = extractor.extractStrings(code);
|
|
206
248
|
|
|
207
249
|
const snippet = snippets[0];
|
|
208
|
-
expect(snippet.originalCode).toBe('"Hello".TR()
|
|
209
|
-
expect(snippet.convertedCode).toBe('"Hello".TR()
|
|
250
|
+
expect(snippet.originalCode).toBe('"Hello".TR()');
|
|
251
|
+
expect(snippet.convertedCode).toBe('"Hello".TR()');
|
|
210
252
|
expect(snippet.literals).toEqual(['Hello']);
|
|
211
253
|
expect(snippet.isChanged).toBe(false);
|
|
212
254
|
});
|
|
213
255
|
|
|
256
|
+
// 测试处理复杂的 `.text =` 赋值语句, 确保能正确处理包含 `string.Format` 调用和 `+` 连接的字符串表达式, 并转换为 `Tr.Format(...)` 形式或进一步递归处理
|
|
214
257
|
test('should handle complex text assignments', () => {
|
|
215
258
|
const code = 'label.text = string.Format("pre{0}sub", Func()) + other;';
|
|
216
259
|
const snippets = extractor.extractStrings(code);
|
|
217
260
|
|
|
218
261
|
const snippet = snippets[0];
|
|
219
|
-
expect(snippet.originalCode).toBe('
|
|
220
|
-
expect(snippet.convertedCode).toBe('
|
|
262
|
+
expect(snippet.originalCode).toBe('string.Format("pre{0}sub", Func()) + other');
|
|
263
|
+
expect(snippet.convertedCode).toBe('Tr.Format("pre{0}sub", Func()) + other.TR()');
|
|
221
264
|
expect(snippet.literals).toEqual(['pre{0}sub']);
|
|
222
265
|
expect(snippet.isChanged).toBe(true);
|
|
223
266
|
});
|
|
224
267
|
|
|
268
|
+
// 测试处理转义字符串, 确保能正确处理包含转义字符的字符串表达式, 并给普通字符串表达式追加 `.TR()` 或者让内插字符串转换为 `Tr.Format(...)` 形式
|
|
225
269
|
test('should handle escaped strings', () => {
|
|
226
270
|
const code = 'a.text = "aaa\\"bbb\\"c\\"d\\\\\\"cc";';
|
|
227
271
|
const snippets = extractor.extractStrings(code);
|
|
228
272
|
|
|
229
273
|
const snippet = snippets[0];
|
|
230
|
-
expect(snippet.originalCode).toBe('
|
|
231
|
-
expect(snippet.convertedCode).toBe('
|
|
274
|
+
expect(snippet.originalCode).toBe('"aaa\\"bbb\\"c\\"d\\\\\\"cc"');
|
|
275
|
+
expect(snippet.convertedCode).toBe('"aaa\\"bbb\\"c\\"d\\\\\\"cc".TR()');
|
|
232
276
|
expect(snippet.literals).toEqual(['aaa\\"bbb\\"c\\"d\\\\\\"cc']);
|
|
233
277
|
expect(snippet.isChanged).toBe(true);
|
|
234
278
|
});
|
|
235
279
|
|
|
280
|
+
// 测试处理 `@$""` 和 `$@""` 格式的字符串表达式, 确保能将其转换为 `Tr.Format(...)` 形式, 并正确提取字符串表达式信息
|
|
236
281
|
test('should handle @$"" and $@"" formats', () => {
|
|
237
282
|
const code = 'Fcx.Kjl(@$"Hello, {name}!");';
|
|
238
283
|
const snippets = extractor.extractStrings(code);
|
|
239
284
|
|
|
240
285
|
const snippet = snippets[0];
|
|
241
|
-
expect(snippet.originalCode).toBe('
|
|
242
|
-
expect(snippet.convertedCode).toBe('
|
|
286
|
+
expect(snippet.originalCode).toBe('@$"Hello, {name}!"');
|
|
287
|
+
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
243
288
|
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
244
289
|
expect(snippet.isChanged).toBe(true);
|
|
245
290
|
});
|
|
246
291
|
|
|
292
|
+
// 测试处理函数调用时, 确保能正确提取参数中的字符串表达式, 不需要给字符串表达式追加 `.TR()` 或 转换为 `Tr.Format(...)` 形式, 除非遇到由 `+` 连接的字符串表达式
|
|
247
293
|
test('should handle function calls with string arguments', () => {
|
|
248
294
|
const code = 'CallFunc("Hello", "World");';
|
|
249
295
|
const snippets = extractor.extractStrings(code);
|
|
296
|
+
{
|
|
297
|
+
const snippet = snippets[0];
|
|
298
|
+
expect(snippet.originalCode).toBe('"Hello"');
|
|
299
|
+
expect(snippet.convertedCode).toBe('"Hello"');
|
|
300
|
+
expect(snippet.literals).toEqual(['Hello']);
|
|
301
|
+
expect(snippet.isChanged).toBe(false);
|
|
302
|
+
}
|
|
303
|
+
{
|
|
250
304
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
305
|
+
const snippet = snippets[1];
|
|
306
|
+
expect(snippet.originalCode).toBe('"World"');
|
|
307
|
+
expect(snippet.convertedCode).toBe('"World"');
|
|
308
|
+
expect(snippet.literals).toEqual(['World']);
|
|
309
|
+
expect(snippet.isChanged).toBe(false);
|
|
310
|
+
}
|
|
256
311
|
});
|
|
257
312
|
|
|
313
|
+
// 测试处理 `.text =` 赋值语句时, 确保能正确处理包含 `Tr.Format(...)` 调用的字符串表达式, 并给普通字符串表达式追加 `.TR()` 或者让内插字符串转换为 `Tr.Format(...)` 形式
|
|
258
314
|
test('should handle .text = with Tr.Format', () => {
|
|
259
315
|
const code = 'label.text = Tr.Format("pre", Func(), "sub") + other;';
|
|
260
316
|
const snippets = extractor.extractStrings(code);
|
|
261
317
|
|
|
262
318
|
const snippet = snippets[0];
|
|
263
|
-
expect(snippet.originalCode).toBe('
|
|
264
|
-
expect(snippet.convertedCode).toBe('
|
|
319
|
+
expect(snippet.originalCode).toBe('Tr.Format("pre", Func(), "sub") + other');
|
|
320
|
+
expect(snippet.convertedCode).toBe('Tr.Format("pre", Func(), "sub") + other.TR()');
|
|
265
321
|
expect(snippet.literals).toEqual(['pre', 'sub']);
|
|
266
322
|
expect(snippet.isChanged).toBe(true);
|
|
267
323
|
});
|
|
268
324
|
|
|
325
|
+
// 测试处理 `.text =` 赋值语句时, 确保能正确处理包含 `Tr.Format(...)` 调用的字符串表达式, 并给普通字符串表达式追加 `.TR()` 或者让内插字符串转换为 `Tr.Format(...)` 形式, 除非遇到由 `+` 连接的字符串表达式
|
|
269
326
|
test('should handle .text = with Tr.Format 2', () => {
|
|
270
327
|
const code = 'm_text_lastAward.text = $"[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]";';
|
|
271
328
|
const snippets = extractor.extractStrings(code);
|
|
272
329
|
|
|
273
330
|
const snippet = snippets[0];
|
|
274
|
-
expect(snippet.originalCode).toBe('
|
|
275
|
-
expect(snippet.convertedCode).toBe('
|
|
331
|
+
expect(snippet.originalCode).toBe('$"[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]"');
|
|
332
|
+
expect(snippet.convertedCode).toBe('$"[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]"');
|
|
276
333
|
expect(snippet.literals).toEqual(['[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]']);
|
|
277
334
|
expect(snippet.isChanged).toBe(false);
|
|
278
335
|
});
|
|
279
336
|
|
|
337
|
+
// 处理C#多行语句
|
|
280
338
|
test('should handle non string assignment 1', () => {
|
|
281
339
|
const code = 'var d1 = 12;var d2 = 13;var d3 = d1 + d2;var aa = "aaa";';
|
|
282
340
|
const snippets = extractor.extractStrings(code);
|
|
283
341
|
{
|
|
284
342
|
const snippet = snippets[0];
|
|
285
|
-
expect(snippet.originalCode).toBe('
|
|
286
|
-
expect(snippet.convertedCode).toBe('
|
|
343
|
+
expect(snippet.originalCode).toBe('"aaa"');
|
|
344
|
+
expect(snippet.convertedCode).toBe('"aaa"');
|
|
287
345
|
expect(snippet.literals).toEqual(['aaa']);
|
|
288
346
|
expect(snippet.isChanged).toBe(false);
|
|
289
347
|
}
|
|
290
348
|
});
|
|
291
349
|
|
|
350
|
+
// 处理C#多行语句
|
|
292
351
|
test('should handle non string assignment 2', () => {
|
|
293
352
|
const code = 'var d3 = d1 + d2;var aa = "aaa";';
|
|
294
353
|
const snippets = extractor.extractStrings(code);
|
|
295
354
|
{
|
|
296
355
|
const snippet = snippets[0];
|
|
297
|
-
expect(snippet.originalCode).toBe('
|
|
298
|
-
expect(snippet.convertedCode).toBe('
|
|
356
|
+
expect(snippet.originalCode).toBe('"aaa"');
|
|
357
|
+
expect(snippet.convertedCode).toBe('"aaa"');
|
|
299
358
|
expect(snippet.literals).toEqual(['aaa']);
|
|
300
359
|
expect(snippet.isChanged).toBe(false);
|
|
301
360
|
}
|
|
302
361
|
});
|
|
303
362
|
|
|
363
|
+
// 处理C#多行语句
|
|
304
364
|
test('should handle multilne content1', () => {
|
|
305
365
|
const code = 'var aa = "aaa";\nvar bb = "bbb";\nvar cc = "ccc";';
|
|
306
366
|
const snippets = extractor.extractStrings(code);
|
|
307
367
|
{
|
|
308
368
|
const snippet = snippets[0];
|
|
309
|
-
expect(snippet.originalCode).toBe('
|
|
310
|
-
expect(snippet.convertedCode).toBe('
|
|
369
|
+
expect(snippet.originalCode).toBe('"aaa"');
|
|
370
|
+
expect(snippet.convertedCode).toBe('"aaa"');
|
|
311
371
|
expect(snippet.literals).toEqual(['aaa']);
|
|
312
372
|
expect(snippet.isChanged).toBe(false);
|
|
313
373
|
}
|
|
314
374
|
{
|
|
315
375
|
const snippet = snippets[1];
|
|
316
|
-
expect(snippet.originalCode).toBe('
|
|
317
|
-
expect(snippet.convertedCode).toBe('
|
|
376
|
+
expect(snippet.originalCode).toBe('"bbb"');
|
|
377
|
+
expect(snippet.convertedCode).toBe('"bbb"');
|
|
318
378
|
expect(snippet.literals).toEqual(['bbb']);
|
|
319
379
|
expect(snippet.isChanged).toBe(false);
|
|
320
380
|
}
|
|
321
381
|
{
|
|
322
382
|
const snippet = snippets[2];
|
|
323
|
-
expect(snippet.originalCode).toBe('
|
|
324
|
-
expect(snippet.convertedCode).toBe('
|
|
383
|
+
expect(snippet.originalCode).toBe('"ccc"');
|
|
384
|
+
expect(snippet.convertedCode).toBe('"ccc"');
|
|
325
385
|
expect(snippet.literals).toEqual(['ccc']);
|
|
326
386
|
expect(snippet.isChanged).toBe(false);
|
|
327
387
|
}
|
|
328
388
|
});
|
|
329
389
|
|
|
390
|
+
// 处理C#多行语句
|
|
330
391
|
test('should handle multilne content2', () => {
|
|
331
392
|
const code = 'var d1 = 12;var d2 = 13;var d3 = d1 + d2;var aa = "aaa";\nvar bb = "bbb";\nvar dd = aa + bb;\nvar hh = aa + bb + "hhh";\ncc.text = "ccc" + aa + bb;var ii = "iii";jj.text = "jjj";CallFunc("jjj");CallFunc2("jjj", "kkk");jj.text = "jjj" + ll;';
|
|
332
393
|
const snippets = extractor.extractStrings(code);
|
|
333
394
|
{
|
|
334
395
|
const snippet = snippets[0];
|
|
335
|
-
expect(snippet.originalCode).toBe('
|
|
336
|
-
expect(snippet.convertedCode).toBe('
|
|
396
|
+
expect(snippet.originalCode).toBe('"aaa"');
|
|
397
|
+
expect(snippet.convertedCode).toBe('"aaa"');
|
|
337
398
|
expect(snippet.literals).toEqual(['aaa']);
|
|
338
399
|
expect(snippet.isChanged).toBe(false);
|
|
339
400
|
}
|
|
340
401
|
{
|
|
341
402
|
const snippet = snippets[1];
|
|
342
|
-
expect(snippet.originalCode).toBe('
|
|
343
|
-
expect(snippet.convertedCode).toBe('
|
|
403
|
+
expect(snippet.originalCode).toBe('"bbb"');
|
|
404
|
+
expect(snippet.convertedCode).toBe('"bbb"');
|
|
344
405
|
expect(snippet.literals).toEqual(['bbb']);
|
|
345
406
|
expect(snippet.isChanged).toBe(false);
|
|
346
407
|
}
|
|
347
408
|
{
|
|
348
409
|
const snippet = snippets[2];
|
|
349
|
-
expect(snippet.originalCode).toBe('
|
|
350
|
-
expect(snippet.convertedCode).toBe('
|
|
410
|
+
expect(snippet.originalCode).toBe('aa + bb + "hhh"');
|
|
411
|
+
expect(snippet.convertedCode).toBe('aa.TR() + bb.TR() + "hhh".TR()');
|
|
351
412
|
expect(snippet.literals).toEqual(['hhh']);
|
|
352
413
|
expect(snippet.isChanged).toBe(true);
|
|
353
414
|
}
|
|
354
415
|
{
|
|
355
416
|
const snippet = snippets[3];
|
|
356
|
-
expect(snippet.originalCode).toBe('
|
|
357
|
-
expect(snippet.convertedCode).toBe('
|
|
417
|
+
expect(snippet.originalCode).toBe('"ccc" + aa + bb');
|
|
418
|
+
expect(snippet.convertedCode).toBe('"ccc".TR() + aa.TR() + bb.TR()');
|
|
358
419
|
expect(snippet.literals).toEqual(['ccc']);
|
|
359
420
|
expect(snippet.isChanged).toBe(true);
|
|
360
421
|
}
|
|
361
422
|
{
|
|
362
423
|
const snippet = snippets[4];
|
|
363
|
-
expect(snippet.originalCode).toBe('
|
|
364
|
-
expect(snippet.convertedCode).toBe('
|
|
424
|
+
expect(snippet.originalCode).toBe('"iii"');
|
|
425
|
+
expect(snippet.convertedCode).toBe('"iii"');
|
|
365
426
|
expect(snippet.literals).toEqual(['iii']);
|
|
366
427
|
expect(snippet.isChanged).toBe(false);
|
|
367
428
|
}
|
|
368
429
|
{
|
|
369
430
|
const snippet = snippets[5];
|
|
370
|
-
expect(snippet.originalCode).toBe('
|
|
371
|
-
expect(snippet.convertedCode).toBe('
|
|
431
|
+
expect(snippet.originalCode).toBe('"jjj"');
|
|
432
|
+
expect(snippet.convertedCode).toBe('"jjj".TR()');
|
|
372
433
|
expect(snippet.literals).toEqual(['jjj']);
|
|
373
434
|
expect(snippet.isChanged).toBe(true);
|
|
374
435
|
}
|
|
375
436
|
{
|
|
376
437
|
const snippet = snippets[6];
|
|
377
|
-
expect(snippet.originalCode).toBe('
|
|
378
|
-
expect(snippet.convertedCode).toBe('
|
|
438
|
+
expect(snippet.originalCode).toBe('"jjj"');
|
|
439
|
+
expect(snippet.convertedCode).toBe('"jjj"');
|
|
379
440
|
expect(snippet.literals).toEqual(['jjj']);
|
|
380
441
|
expect(snippet.isChanged).toBe(false);
|
|
381
442
|
}
|
|
382
443
|
{
|
|
383
444
|
const snippet = snippets[7];
|
|
384
|
-
expect(snippet.originalCode).toBe('
|
|
385
|
-
expect(snippet.convertedCode).toBe('
|
|
386
|
-
expect(snippet.literals).toEqual(['jjj'
|
|
445
|
+
expect(snippet.originalCode).toBe('"jjj"');
|
|
446
|
+
expect(snippet.convertedCode).toBe('"jjj"');
|
|
447
|
+
expect(snippet.literals).toEqual(['jjj']);
|
|
387
448
|
expect(snippet.isChanged).toBe(false);
|
|
388
449
|
}
|
|
389
450
|
{
|
|
390
451
|
const snippet = snippets[8];
|
|
391
|
-
expect(snippet.originalCode).toBe('
|
|
392
|
-
expect(snippet.convertedCode).toBe('
|
|
452
|
+
expect(snippet.originalCode).toBe('"kkk"');
|
|
453
|
+
expect(snippet.convertedCode).toBe('"kkk"');
|
|
454
|
+
expect(snippet.literals).toEqual(['kkk']);
|
|
455
|
+
expect(snippet.isChanged).toBe(false);
|
|
456
|
+
}
|
|
457
|
+
{
|
|
458
|
+
const snippet = snippets[9];
|
|
459
|
+
expect(snippet.originalCode).toBe('"jjj" + ll');
|
|
460
|
+
expect(snippet.convertedCode).toBe('"jjj".TR() + ll.TR()');
|
|
393
461
|
expect(snippet.literals).toEqual(['jjj']);
|
|
394
462
|
expect(snippet.isChanged).toBe(true);
|
|
395
463
|
}
|
|
396
464
|
});
|
|
397
465
|
|
|
466
|
+
// 处理C#多行语句
|
|
398
467
|
test('should handle multilne content3', () => {
|
|
399
468
|
const code = 'label.text = Tr.Format("pre", Func(), "sub") + other;\nlabel2.text = Tr.Format("pre2", Func(), "sub2") + other2;';
|
|
400
469
|
const snippets = extractor.extractStrings(code);
|
|
401
470
|
{
|
|
402
471
|
const snippet = snippets[0];
|
|
403
|
-
expect(snippet.originalCode).toBe('
|
|
404
|
-
expect(snippet.convertedCode).toBe('
|
|
472
|
+
expect(snippet.originalCode).toBe('Tr.Format("pre", Func(), "sub") + other');
|
|
473
|
+
expect(snippet.convertedCode).toBe('Tr.Format("pre", Func(), "sub") + other.TR()');
|
|
405
474
|
expect(snippet.literals).toEqual(['pre', 'sub']);
|
|
406
475
|
expect(snippet.isChanged).toBe(true);
|
|
407
476
|
}
|
|
408
477
|
{
|
|
409
478
|
const snippet = snippets[1];
|
|
410
|
-
expect(snippet.originalCode).toBe('
|
|
411
|
-
expect(snippet.convertedCode).toBe('
|
|
479
|
+
expect(snippet.originalCode).toBe('Tr.Format("pre2", Func(), "sub2") + other2');
|
|
480
|
+
expect(snippet.convertedCode).toBe('Tr.Format("pre2", Func(), "sub2") + other2.TR()');
|
|
412
481
|
expect(snippet.literals).toEqual(['pre2', 'sub2']);
|
|
413
482
|
expect(snippet.isChanged).toBe(true);
|
|
414
483
|
}
|
|
415
484
|
});
|
|
416
485
|
|
|
486
|
+
// 处理C#多行语句
|
|
417
487
|
test('should handle multilne content4', () => {
|
|
418
488
|
const code = 'label.text =\n Tr.Format(\n\t"pre", Func(),\n\t\t "sub") + other;';
|
|
419
489
|
const snippets = extractor.extractStrings(code);
|
|
420
490
|
{
|
|
421
491
|
const snippet = snippets[0];
|
|
422
|
-
expect(snippet.originalCode).toBe('
|
|
423
|
-
expect(snippet.convertedCode).toBe('
|
|
492
|
+
expect(snippet.originalCode).toBe('Tr.Format(\n\t"pre", Func(),\n\t\t "sub") + other');
|
|
493
|
+
expect(snippet.convertedCode).toBe('Tr.Format(\n\t"pre", Func(),\n\t\t "sub") + other.TR()');
|
|
424
494
|
expect(snippet.literals).toEqual(['pre', 'sub']);
|
|
425
495
|
expect(snippet.isChanged).toBe(true);
|
|
426
496
|
}
|
|
427
497
|
});
|
|
428
498
|
|
|
499
|
+
// 处理C#多行语句
|
|
429
500
|
test('should handle multilne content5', () => {
|
|
430
501
|
const code = `
|
|
431
|
-
|
|
502
|
+
// 注释中无字符串表达式时, 不需要包含在捕获部分里
|
|
432
503
|
m_text_name.text = cardTable.Name;
|
|
433
504
|
`;
|
|
434
505
|
const snippets = extractor.extractStrings(code);
|
|
435
506
|
{
|
|
436
507
|
const snippet = snippets[0];
|
|
437
|
-
expect(snippet.originalCode).toBe('
|
|
438
|
-
expect(snippet.convertedCode).toBe('
|
|
508
|
+
expect(snippet.originalCode).toBe('cardTable.Name');
|
|
509
|
+
expect(snippet.convertedCode).toBe('cardTable.Name.TR()');
|
|
439
510
|
expect(snippet.literals).toEqual([]);
|
|
440
511
|
expect(snippet.isChanged).toBe(true);
|
|
441
512
|
}
|
|
442
513
|
});
|
|
443
514
|
|
|
515
|
+
// 处理C#多行语句
|
|
444
516
|
test('should handle multilne content6', () => {
|
|
445
517
|
const code = `
|
|
446
518
|
if (condition)
|
|
@@ -451,14 +523,15 @@ describe('CSharpStringExtractor', () => {
|
|
|
451
523
|
const snippets = extractor.extractStrings(code);
|
|
452
524
|
{
|
|
453
525
|
const snippet = snippets[0];
|
|
454
|
-
expect(snippet.originalCode).toBe('
|
|
455
|
-
expect(snippet.convertedCode).toBe('
|
|
526
|
+
expect(snippet.originalCode).toBe('"卸载成功"');
|
|
527
|
+
expect(snippet.convertedCode).toBe('"卸载成功"');
|
|
456
528
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
457
|
-
expect(snippet.originalIndex).toBe(code.indexOf('
|
|
529
|
+
expect(snippet.originalIndex).toBe(code.indexOf('"卸载成功"'));
|
|
458
530
|
expect(snippet.isChanged).toBe(false);
|
|
459
531
|
}
|
|
460
532
|
});
|
|
461
533
|
|
|
534
|
+
// 处理C#多行语句
|
|
462
535
|
test('should handle multilne content7', () => {
|
|
463
536
|
const code = `
|
|
464
537
|
while (condition)
|
|
@@ -469,14 +542,15 @@ describe('CSharpStringExtractor', () => {
|
|
|
469
542
|
const snippets = extractor.extractStrings(code);
|
|
470
543
|
{
|
|
471
544
|
const snippet = snippets[0];
|
|
472
|
-
expect(snippet.originalCode).toBe('
|
|
473
|
-
expect(snippet.convertedCode).toBe('
|
|
545
|
+
expect(snippet.originalCode).toBe('"卸载成功"');
|
|
546
|
+
expect(snippet.convertedCode).toBe('"卸载成功"');
|
|
474
547
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
475
|
-
expect(snippet.originalIndex).toBe(code.indexOf('
|
|
548
|
+
expect(snippet.originalIndex).toBe(code.indexOf('"卸载成功"'));
|
|
476
549
|
expect(snippet.isChanged).toBe(false);
|
|
477
550
|
}
|
|
478
551
|
});
|
|
479
552
|
|
|
553
|
+
// 处理C#多行语句
|
|
480
554
|
test('should handle multilne content8', () => {
|
|
481
555
|
const code = `
|
|
482
556
|
for (scope;condition;continuex)
|
|
@@ -487,13 +561,14 @@ describe('CSharpStringExtractor', () => {
|
|
|
487
561
|
const snippets = extractor.extractStrings(code);
|
|
488
562
|
{
|
|
489
563
|
const snippet = snippets[0];
|
|
490
|
-
expect(snippet.originalCode).toBe('
|
|
491
|
-
expect(snippet.convertedCode).toBe('
|
|
564
|
+
expect(snippet.originalCode).toBe('"卸载成功"');
|
|
565
|
+
expect(snippet.convertedCode).toBe('"卸载成功"');
|
|
492
566
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
493
567
|
expect(snippet.isChanged).toBe(false);
|
|
494
568
|
}
|
|
495
569
|
});
|
|
496
570
|
|
|
571
|
+
// 处理C#多行语句
|
|
497
572
|
test('should handle multilne content9', () => {
|
|
498
573
|
const code = `
|
|
499
574
|
{
|
|
@@ -503,13 +578,14 @@ describe('CSharpStringExtractor', () => {
|
|
|
503
578
|
const snippets = extractor.extractStrings(code);
|
|
504
579
|
{
|
|
505
580
|
const snippet = snippets[0];
|
|
506
|
-
expect(snippet.originalCode).toBe('
|
|
507
|
-
expect(snippet.convertedCode).toBe('
|
|
581
|
+
expect(snippet.originalCode).toBe('"卸载成功"');
|
|
582
|
+
expect(snippet.convertedCode).toBe('"卸载成功"');
|
|
508
583
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
509
584
|
expect(snippet.isChanged).toBe(false);
|
|
510
585
|
}
|
|
511
586
|
});
|
|
512
587
|
|
|
588
|
+
// 处理C#多行语句
|
|
513
589
|
test('should handle multilne content10', () => {
|
|
514
590
|
const code = `
|
|
515
591
|
var lambda1 = () => {
|
|
@@ -519,13 +595,14 @@ describe('CSharpStringExtractor', () => {
|
|
|
519
595
|
const snippets = extractor.extractStrings(code);
|
|
520
596
|
{
|
|
521
597
|
const snippet = snippets[0];
|
|
522
|
-
expect(snippet.originalCode).toBe('
|
|
523
|
-
expect(snippet.convertedCode).toBe('
|
|
598
|
+
expect(snippet.originalCode).toBe('"卸载成功"');
|
|
599
|
+
expect(snippet.convertedCode).toBe('"卸载成功"');
|
|
524
600
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
525
601
|
expect(snippet.isChanged).toBe(false);
|
|
526
602
|
}
|
|
527
603
|
});
|
|
528
604
|
|
|
605
|
+
// 处理C#多行语句
|
|
529
606
|
test('should handle multilne content11', () => {
|
|
530
607
|
const code = `
|
|
531
608
|
void lambda1() {
|
|
@@ -535,13 +612,14 @@ describe('CSharpStringExtractor', () => {
|
|
|
535
612
|
const snippets = extractor.extractStrings(code);
|
|
536
613
|
{
|
|
537
614
|
const snippet = snippets[0];
|
|
538
|
-
expect(snippet.originalCode).toBe('
|
|
539
|
-
expect(snippet.convertedCode).toBe('
|
|
615
|
+
expect(snippet.originalCode).toBe('"卸载成功"');
|
|
616
|
+
expect(snippet.convertedCode).toBe('"卸载成功"');
|
|
540
617
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
541
618
|
expect(snippet.isChanged).toBe(false);
|
|
542
619
|
}
|
|
543
620
|
});
|
|
544
621
|
|
|
622
|
+
// 处理C#多行语句
|
|
545
623
|
test('should handle multilne content12', () => {
|
|
546
624
|
const code = `
|
|
547
625
|
//星级
|
|
@@ -562,12 +640,14 @@ describe('CSharpStringExtractor', () => {
|
|
|
562
640
|
const snippets = extractor.extractStrings(code);
|
|
563
641
|
{
|
|
564
642
|
const snippet = snippets[0];
|
|
565
|
-
expect(snippet.originalCode).toBe('
|
|
566
|
-
expect(snippet.convertedCode).toBe('
|
|
643
|
+
expect(snippet.originalCode).toBe('Tr.Format("{0}阶", _sutraCardData.Quality)');
|
|
644
|
+
expect(snippet.convertedCode).toBe('Tr.Format("{0}阶", _sutraCardData.Quality)');
|
|
567
645
|
expect(snippet.literals).toEqual(['{0}阶']);
|
|
568
646
|
expect(snippet.isChanged).toBe(false);
|
|
569
647
|
}
|
|
570
648
|
});
|
|
649
|
+
|
|
650
|
+
// 处理C#多行语句
|
|
571
651
|
test('should handle multilne content13', () => {
|
|
572
652
|
const code = `
|
|
573
653
|
Toast.Info("卸载成功");
|
|
@@ -576,22 +656,23 @@ describe('CSharpStringExtractor', () => {
|
|
|
576
656
|
const snippets = extractor.extractStrings(code);
|
|
577
657
|
{
|
|
578
658
|
const snippet = snippets[0];
|
|
579
|
-
expect(snippet.originalIndex).toBe(code.indexOf('
|
|
580
|
-
expect(snippet.originalCode).toBe('
|
|
581
|
-
expect(snippet.convertedCode).toBe('
|
|
659
|
+
expect(snippet.originalIndex).toBe(code.indexOf('"卸载成功"'));
|
|
660
|
+
expect(snippet.originalCode).toBe('"卸载成功"');
|
|
661
|
+
expect(snippet.convertedCode).toBe('"卸载成功"');
|
|
582
662
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
583
663
|
expect(snippet.isChanged).toBe(false);
|
|
584
664
|
}
|
|
585
665
|
{
|
|
586
666
|
const snippet = snippets[1];
|
|
587
|
-
expect(snippet.originalIndex).toBe(code.indexOf('
|
|
588
|
-
expect(snippet.originalCode).toBe('
|
|
589
|
-
expect(snippet.convertedCode).toBe('
|
|
667
|
+
expect(snippet.originalIndex).toBe(code.indexOf('"卸载成功"', snippets[0].originalIndex + 1));
|
|
668
|
+
expect(snippet.originalCode).toBe('"卸载成功"');
|
|
669
|
+
expect(snippet.convertedCode).toBe('"卸载成功"');
|
|
590
670
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
591
671
|
expect(snippet.isChanged).toBe(false);
|
|
592
672
|
}
|
|
593
673
|
});
|
|
594
674
|
|
|
675
|
+
// 处理C#多行语句
|
|
595
676
|
test('should handle multilne content14', () => {
|
|
596
677
|
const code = readFileSync('./test/MainSutraDetailDialog.cs', 'utf8');
|
|
597
678
|
const snippets = extractor.extractStrings(code);
|
|
@@ -602,129 +683,178 @@ describe('CSharpStringExtractor', () => {
|
|
|
602
683
|
// 针对每个snippet展开对每个属性值的断言
|
|
603
684
|
|
|
604
685
|
// Snippet 1
|
|
605
|
-
expect(snippets[0].originalIndex).toBe(
|
|
606
|
-
expect(snippets[0].originalCode).toBe('
|
|
607
|
-
expect(snippets[0].convertedCode).toBe('
|
|
686
|
+
expect(snippets[0].originalIndex).toBe(code.indexOf('cardTable.Name.TR()'));
|
|
687
|
+
expect(snippets[0].originalCode).toBe('cardTable.Name.TR()');
|
|
688
|
+
expect(snippets[0].convertedCode).toBe('cardTable.Name.TR()');
|
|
608
689
|
expect(snippets[0].literals).toEqual([]);
|
|
609
690
|
expect(snippets[0].isChanged).toBe(false);
|
|
610
691
|
|
|
611
692
|
// Snippet 2
|
|
612
|
-
expect(snippets[1].originalIndex).toBe(
|
|
613
|
-
expect(snippets[1].originalCode).toBe('
|
|
614
|
-
expect(snippets[1].convertedCode).toBe('
|
|
693
|
+
expect(snippets[1].originalIndex).toBe(code.indexOf('sutraConfig.Poetry[0].TR()'));
|
|
694
|
+
expect(snippets[1].originalCode).toBe('sutraConfig.Poetry[0].TR()');
|
|
695
|
+
expect(snippets[1].convertedCode).toBe('sutraConfig.Poetry[0].TR()');
|
|
615
696
|
expect(snippets[1].literals).toEqual([]);
|
|
616
697
|
expect(snippets[1].isChanged).toBe(false);
|
|
617
698
|
|
|
618
699
|
// Snippet 3
|
|
619
|
-
expect(snippets[2].originalIndex).toBe(
|
|
620
|
-
expect(snippets[2].originalCode).toBe('
|
|
621
|
-
expect(snippets[2].convertedCode).toBe('
|
|
700
|
+
expect(snippets[2].originalIndex).toBe(code.indexOf('sutraConfig.Poetry[1].TR()'));
|
|
701
|
+
expect(snippets[2].originalCode).toBe('sutraConfig.Poetry[1].TR()');
|
|
702
|
+
expect(snippets[2].convertedCode).toBe('sutraConfig.Poetry[1].TR()');
|
|
622
703
|
expect(snippets[2].literals).toEqual([]);
|
|
623
704
|
expect(snippets[2].isChanged).toBe(false);
|
|
624
705
|
|
|
625
706
|
// Snippet 4
|
|
626
|
-
expect(snippets[3].originalIndex).toBe(
|
|
627
|
-
expect(snippets[3].originalCode).toBe('
|
|
628
|
-
expect(snippets[3].convertedCode).toBe('
|
|
707
|
+
expect(snippets[3].originalIndex).toBe(code.indexOf('(_sutraCardData.AttackUp() / 100).ToString("0.0") + "%".TR()'));
|
|
708
|
+
expect(snippets[3].originalCode).toBe('(_sutraCardData.AttackUp() / 100).ToString("0.0") + "%".TR()');
|
|
709
|
+
expect(snippets[3].convertedCode).toBe('(_sutraCardData.AttackUp() / 100).ToString("0.0").TR() + "%".TR()');
|
|
629
710
|
expect(snippets[3].literals).toEqual(['0.0', '%']);
|
|
630
711
|
expect(snippets[3].isChanged).toBe(true);
|
|
631
712
|
|
|
632
713
|
// Snippet 5
|
|
633
|
-
expect(snippets[4].originalIndex).toBe(
|
|
634
|
-
expect(snippets[4].originalCode).toBe('
|
|
635
|
-
expect(snippets[4].convertedCode).toBe('
|
|
714
|
+
expect(snippets[4].originalIndex).toBe(code.indexOf('(_sutraCardData.HpUp() / 100).ToString("0.0") + "%".TR()'));
|
|
715
|
+
expect(snippets[4].originalCode).toBe('(_sutraCardData.HpUp() / 100).ToString("0.0") + "%".TR()');
|
|
716
|
+
expect(snippets[4].convertedCode).toBe('(_sutraCardData.HpUp() / 100).ToString("0.0").TR() + "%".TR()');
|
|
636
717
|
expect(snippets[4].literals).toEqual(['0.0', '%']);
|
|
637
718
|
expect(snippets[4].isChanged).toBe(true);
|
|
638
719
|
|
|
639
720
|
// Snippet 6
|
|
640
|
-
expect(snippets[5].originalIndex).toBe(
|
|
641
|
-
expect(snippets[5].originalCode).toBe('
|
|
642
|
-
expect(snippets[5].convertedCode).toBe('
|
|
721
|
+
expect(snippets[5].originalIndex).toBe(code.indexOf('skillConfig.Name.TR()'));
|
|
722
|
+
expect(snippets[5].originalCode).toBe('skillConfig.Name.TR()');
|
|
723
|
+
expect(snippets[5].convertedCode).toBe('skillConfig.Name.TR()');
|
|
643
724
|
expect(snippets[5].literals).toEqual([]);
|
|
644
725
|
expect(snippets[5].isChanged).toBe(false);
|
|
645
726
|
|
|
646
727
|
// Snippet 7
|
|
647
|
-
expect(snippets[6].originalIndex).toBe(
|
|
648
|
-
expect(snippets[6].originalCode).toBe('
|
|
649
|
-
expect(snippets[6].convertedCode).toBe('
|
|
728
|
+
expect(snippets[6].originalIndex).toBe(code.indexOf('passiveSkillConfig != null ? passiveSkillConfig.Description.TR() : "被动技能未解锁".TR()'));
|
|
729
|
+
expect(snippets[6].originalCode).toBe('passiveSkillConfig != null ? passiveSkillConfig.Description.TR() : "被动技能未解锁".TR()');
|
|
730
|
+
expect(snippets[6].convertedCode).toBe('passiveSkillConfig != null ? passiveSkillConfig.Description.TR() : "被动技能未解锁".TR()');
|
|
650
731
|
expect(snippets[6].literals).toEqual(['被动技能未解锁']);
|
|
651
732
|
expect(snippets[6].isChanged).toBe(false);
|
|
652
733
|
|
|
653
734
|
// Snippet 8
|
|
654
|
-
expect(snippets[7].originalIndex).toBe(
|
|
655
|
-
expect(snippets[7].originalCode).toBe('
|
|
656
|
-
expect(snippets[7].convertedCode).toBe('
|
|
735
|
+
expect(snippets[7].originalIndex).toBe(code.indexOf('"Effect_FaBao_Unlock"'));
|
|
736
|
+
expect(snippets[7].originalCode).toBe('"Effect_FaBao_Unlock"');
|
|
737
|
+
expect(snippets[7].convertedCode).toBe('"Effect_FaBao_Unlock"');
|
|
657
738
|
expect(snippets[7].literals).toEqual(['Effect_FaBao_Unlock']);
|
|
658
739
|
expect(snippets[7].isChanged).toBe(false);
|
|
659
740
|
|
|
660
741
|
// Snippet 9
|
|
661
|
-
expect(snippets[8].originalIndex).toBe(
|
|
662
|
-
expect(snippets[8].originalCode).toBe('
|
|
663
|
-
expect(snippets[8].convertedCode).toBe('
|
|
742
|
+
expect(snippets[8].originalIndex).toBe(code.indexOf('Tr.Format("{0}阶", _sutraCardData.Quality)'));
|
|
743
|
+
expect(snippets[8].originalCode).toBe('Tr.Format("{0}阶", _sutraCardData.Quality)');
|
|
744
|
+
expect(snippets[8].convertedCode).toBe('Tr.Format("{0}阶", _sutraCardData.Quality)');
|
|
664
745
|
expect(snippets[8].literals).toEqual(['{0}阶']);
|
|
665
746
|
expect(snippets[8].isChanged).toBe(false);
|
|
666
747
|
|
|
667
748
|
// Snippet 10
|
|
668
|
-
expect(snippets[9].originalIndex).toBe(
|
|
669
|
-
expect(snippets[9].originalCode).toBe('
|
|
670
|
-
expect(snippets[9].convertedCode).toBe('
|
|
749
|
+
expect(snippets[9].originalIndex).toBe(code.indexOf('"通玄:".TR() + (_sutraCardData.InheritAtkPercent / 100).ToString("0.0") + "%".TR()'));
|
|
750
|
+
expect(snippets[9].originalCode).toBe('"通玄:".TR() + (_sutraCardData.InheritAtkPercent / 100).ToString("0.0") + "%".TR()');
|
|
751
|
+
expect(snippets[9].convertedCode).toBe('"通玄:".TR() + (_sutraCardData.InheritAtkPercent / 100).ToString("0.0").TR() + "%".TR()');
|
|
671
752
|
expect(snippets[9].literals).toEqual(['通玄:', '0.0', '%']);
|
|
672
753
|
expect(snippets[9].isChanged).toBe(true);
|
|
673
754
|
|
|
674
755
|
// Snippet 11
|
|
675
|
-
expect(snippets[10].originalIndex).toBe(
|
|
676
|
-
|
|
756
|
+
expect(snippets[10].originalIndex).toBe(code.indexOf(`enough
|
|
757
|
+
? Tr.Format("[color=#1B8049]{0}/{1}[/color]", curCount, costCount)
|
|
758
|
+
: Tr.Format("[color=#E55E5A]{0}/{1}[/color]", curCount, costCount)`));
|
|
759
|
+
expect(snippets[10].originalCode).toBe(`enough
|
|
677
760
|
? Tr.Format("[color=#1B8049]{0}/{1}[/color]", curCount, costCount)
|
|
678
|
-
: Tr.Format("[color=#E55E5A]{0}/{1}[/color]", curCount, costCount)
|
|
679
|
-
expect(snippets[10].convertedCode).toBe(`
|
|
761
|
+
: Tr.Format("[color=#E55E5A]{0}/{1}[/color]", curCount, costCount)`);
|
|
762
|
+
expect(snippets[10].convertedCode).toBe(`enough
|
|
680
763
|
? Tr.Format("[color=#1B8049]{0}/{1}[/color]", curCount, costCount)
|
|
681
|
-
: Tr.Format("[color=#E55E5A]{0}/{1}[/color]", curCount, costCount)
|
|
764
|
+
: Tr.Format("[color=#E55E5A]{0}/{1}[/color]", curCount, costCount)`);
|
|
682
765
|
expect(snippets[10].literals).toEqual(['[color=#1B8049]{0}/{1}[/color]', '[color=#E55E5A]{0}/{1}[/color]']);
|
|
683
766
|
expect(snippets[10].isChanged).toBe(false);
|
|
684
767
|
|
|
685
768
|
// Snippet 12
|
|
686
|
-
expect(snippets[11].originalIndex).toBe(
|
|
687
|
-
expect(snippets[11].originalCode).toBe('
|
|
688
|
-
expect(snippets[11].convertedCode).toBe('
|
|
769
|
+
expect(snippets[11].originalIndex).toBe(code.indexOf('dependLockInfo.Item2.TR()'));
|
|
770
|
+
expect(snippets[11].originalCode).toBe('dependLockInfo.Item2.TR()');
|
|
771
|
+
expect(snippets[11].convertedCode).toBe('dependLockInfo.Item2.TR()');
|
|
689
772
|
expect(snippets[11].literals).toEqual([]);
|
|
690
773
|
expect(snippets[11].isChanged).toBe(false);
|
|
691
774
|
|
|
692
775
|
// Snippet 13
|
|
693
|
-
expect(snippets[12].originalIndex).toBe(
|
|
694
|
-
expect(snippets[12].originalCode).toBe('
|
|
695
|
-
expect(snippets[12].convertedCode).toBe('
|
|
776
|
+
expect(snippets[12].originalIndex).toBe(code.indexOf('"Effect_FaBao_Unlock"', code.indexOf('"Effect_FaBao_Unlock"') + 1));
|
|
777
|
+
expect(snippets[12].originalCode).toBe('"Effect_FaBao_Unlock"');
|
|
778
|
+
expect(snippets[12].convertedCode).toBe('"Effect_FaBao_Unlock"');
|
|
696
779
|
expect(snippets[12].literals).toEqual(['Effect_FaBao_Unlock']);
|
|
697
780
|
expect(snippets[12].isChanged).toBe(false);
|
|
698
781
|
|
|
699
782
|
// Snippet 14
|
|
700
|
-
expect(snippets[13].originalIndex).toBe(
|
|
701
|
-
expect(snippets[13].originalCode).toBe('
|
|
702
|
-
expect(snippets[13].convertedCode).toBe('
|
|
703
|
-
expect(snippets[13].literals).toEqual([]);
|
|
783
|
+
expect(snippets[13].originalIndex).toBe(code.indexOf('Tr.Format("({0}/6)", _sutraCardData.Card.RuneOpenCount)'));
|
|
784
|
+
expect(snippets[13].originalCode).toBe('Tr.Format("({0}/6)", _sutraCardData.Card.RuneOpenCount)');
|
|
785
|
+
expect(snippets[13].convertedCode).toBe('Tr.Format("({0}/6)", _sutraCardData.Card.RuneOpenCount)');
|
|
786
|
+
expect(snippets[13].literals).toEqual(['({0}/6)']);
|
|
704
787
|
expect(snippets[13].isChanged).toBe(false);
|
|
705
788
|
|
|
706
789
|
// Snippet 15
|
|
707
|
-
expect(snippets[14].originalIndex).toBe(
|
|
708
|
-
expect(snippets[14].originalCode).toBe('
|
|
709
|
-
expect(snippets[14].convertedCode).toBe('
|
|
790
|
+
expect(snippets[14].originalIndex).toBe(code.indexOf('$"Can not find tagId in sutra : {_sutraCardData.Card.Id}"'));
|
|
791
|
+
expect(snippets[14].originalCode).toBe('$"Can not find tagId in sutra : {_sutraCardData.Card.Id}"');
|
|
792
|
+
expect(snippets[14].convertedCode).toBe('Tr.Format("Can not find tagId in sutra : {0}", _sutraCardData.Card.Id)');
|
|
710
793
|
expect(snippets[14].literals).toEqual(['Can not find tagId in sutra : {0}']);
|
|
711
794
|
expect(snippets[14].isChanged).toBe(true);
|
|
712
795
|
|
|
796
|
+
//#region 需要捕获类成员赋值表达式中, 出现在赋值操作符`=`右侧的字符串值表达式
|
|
713
797
|
// Snippet 16
|
|
714
|
-
expect(snippets[15].originalIndex).
|
|
715
|
-
expect(snippets[15].
|
|
716
|
-
expect(snippets[15].
|
|
717
|
-
expect(snippets[15].
|
|
798
|
+
expect(snippets[15].originalIndex).toBeGreaterThan(0);
|
|
799
|
+
expect(snippets[15].originalIndex).toBe(code.indexOf('"提示"'));
|
|
800
|
+
expect(snippets[15].originalCode).toBe('"提示"');
|
|
801
|
+
expect(snippets[15].convertedCode).toBe('"提示"');
|
|
802
|
+
expect(snippets[15].literals).toEqual(['提示']);
|
|
718
803
|
expect(snippets[15].isChanged).toBe(false);
|
|
719
804
|
|
|
720
805
|
// Snippet 17
|
|
721
|
-
expect(snippets[16].originalIndex).
|
|
722
|
-
expect(snippets[16].
|
|
723
|
-
expect(snippets[16].
|
|
724
|
-
expect(snippets[16].
|
|
806
|
+
expect(snippets[16].originalIndex).toBeGreaterThan(0);
|
|
807
|
+
expect(snippets[16].originalIndex).toBe(code.indexOf('"是否一键卸下法宝当前镶嵌灵纹"'));
|
|
808
|
+
expect(snippets[16].originalCode).toBe('"是否一键卸下法宝当前镶嵌灵纹"');
|
|
809
|
+
expect(snippets[16].convertedCode).toBe('"是否一键卸下法宝当前镶嵌灵纹"');
|
|
810
|
+
expect(snippets[16].literals).toEqual(['是否一键卸下法宝当前镶嵌灵纹']);
|
|
725
811
|
expect(snippets[16].isChanged).toBe(false);
|
|
812
|
+
|
|
813
|
+
// Snippet 18
|
|
814
|
+
expect(snippets[17].originalIndex).toBeGreaterThan(0);
|
|
815
|
+
expect(snippets[17].originalIndex).toBe(code.indexOf('"确认"'));
|
|
816
|
+
expect(snippets[17].originalCode).toBe('"确认"');
|
|
817
|
+
expect(snippets[17].convertedCode).toBe('"确认"');
|
|
818
|
+
expect(snippets[17].literals).toEqual(['确认']);
|
|
819
|
+
expect(snippets[17].isChanged).toBe(false);
|
|
820
|
+
//#endregion 需要捕获类成员赋值句式中, 出现在赋值操作符`=`右侧的字符串值表达式
|
|
821
|
+
|
|
822
|
+
// Snippet 19
|
|
823
|
+
expect(snippets[18].originalIndex).toBeGreaterThan(0);
|
|
824
|
+
expect(snippets[18].originalIndex).toBe(code.indexOf('"卸载成功"'));
|
|
825
|
+
expect(snippets[18].originalCode).toBe('"卸载成功"');
|
|
826
|
+
expect(snippets[18].convertedCode).toBe('"卸载成功"');
|
|
827
|
+
expect(snippets[18].literals).toEqual(['卸载成功']);
|
|
828
|
+
expect(snippets[18].isChanged).toBe(false);
|
|
829
|
+
|
|
830
|
+
//#region 需要捕获类成员赋值句式中, 出现在赋值操作符`=`右侧的字符串值表达式
|
|
831
|
+
// Snippet 20
|
|
832
|
+
expect(snippets[19].originalIndex).toBeGreaterThan(0);
|
|
833
|
+
expect(snippets[19].originalIndex).toBe(code.indexOf('"取消"'));
|
|
834
|
+
expect(snippets[19].originalCode).toBe('"取消"');
|
|
835
|
+
expect(snippets[19].convertedCode).toBe('"取消"');
|
|
836
|
+
expect(snippets[19].literals).toEqual(['取消']);
|
|
837
|
+
expect(snippets[19].isChanged).toBe(false);
|
|
838
|
+
|
|
839
|
+
// Snippet 21
|
|
840
|
+
expect(snippets[20].originalIndex).toBeGreaterThan(0);
|
|
841
|
+
expect(snippets[20].originalIndex).toBe(code.indexOf('"本次登录不再提示"'));
|
|
842
|
+
expect(snippets[20].originalCode).toBe('"本次登录不再提示"');
|
|
843
|
+
expect(snippets[20].convertedCode).toBe('"本次登录不再提示"');
|
|
844
|
+
expect(snippets[20].literals).toEqual(['本次登录不再提示']);
|
|
845
|
+
expect(snippets[20].isChanged).toBe(false);
|
|
846
|
+
//#endregion 需要捕获类成员赋值句式中, 出现在赋值操作符`=`右侧的字符串值表达式
|
|
847
|
+
|
|
848
|
+
// Snippet 22
|
|
849
|
+
expect(snippets[21].originalIndex).toBeGreaterThan(0);
|
|
850
|
+
expect(snippets[21].originalIndex).toBe(code.indexOf('"卸载成功"', code.indexOf('"卸载成功"') + 1));
|
|
851
|
+
expect(snippets[21].originalCode).toBe('"卸载成功"');
|
|
852
|
+
expect(snippets[21].convertedCode).toBe('"卸载成功"');
|
|
853
|
+
expect(snippets[21].literals).toEqual(['卸载成功']);
|
|
854
|
+
expect(snippets[21].isChanged).toBe(false);
|
|
726
855
|
});
|
|
727
856
|
|
|
857
|
+
// 处理C#多行语句
|
|
728
858
|
test('should handle multilne content15', () => {
|
|
729
859
|
const code = readFileSync('./test/GuildDonateDialog.cs', 'utf8');
|
|
730
860
|
const snippets = extractor.extractStrings(code);
|
|
@@ -739,16 +869,17 @@ describe('CSharpStringExtractor', () => {
|
|
|
739
869
|
expect(targetSnippet).toBeDefined();
|
|
740
870
|
|
|
741
871
|
if (targetSnippet) {
|
|
742
|
-
expect(targetSnippet.originalIndex).toBe(
|
|
743
|
-
expect(targetSnippet.originalCode).toBe(
|
|
744
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
872
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{paidConfig.Quantity}"`));
|
|
873
|
+
expect(targetSnippet.originalCode).toBe(`$"<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{paidConfig.Quantity}"`);
|
|
874
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{0}", paidConfig.Quantity)`);
|
|
745
875
|
expect(targetSnippet.literals).toEqual(["<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{0}"]);
|
|
746
876
|
expect(targetSnippet.isChanged).toBe(true);
|
|
747
877
|
}
|
|
748
878
|
|
|
749
879
|
});
|
|
750
880
|
|
|
751
|
-
|
|
881
|
+
// 处理C#普通字符串包含 `//` 的情形
|
|
882
|
+
test('should handle string with `//`', () => {
|
|
752
883
|
const code = `m_btn_paid.text = "//";`
|
|
753
884
|
const snippets = extractor.extractStrings(code);
|
|
754
885
|
|
|
@@ -756,13 +887,14 @@ describe('CSharpStringExtractor', () => {
|
|
|
756
887
|
expect(snippets.length).toBeGreaterThan(0);
|
|
757
888
|
|
|
758
889
|
let targetSnippet = snippets[0];
|
|
759
|
-
expect(targetSnippet.originalCode).toBe(`
|
|
760
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
890
|
+
expect(targetSnippet.originalCode).toBe(`"//"`);
|
|
891
|
+
expect(targetSnippet.convertedCode).toBe(`"//".TR()`);
|
|
761
892
|
expect(targetSnippet.literals).toEqual(['//']);
|
|
762
893
|
expect(targetSnippet.isChanged).toBe(true);
|
|
763
894
|
|
|
764
895
|
});
|
|
765
896
|
|
|
897
|
+
// 处理C# `+=` 形式赋值语句
|
|
766
898
|
test('should handle string template with format specifier', () => {
|
|
767
899
|
const code = `infoStr += $"最终抗性: {resistReduce:F}\\n";`
|
|
768
900
|
const snippets = extractor.extractStrings(code);
|
|
@@ -771,12 +903,13 @@ describe('CSharpStringExtractor', () => {
|
|
|
771
903
|
expect(snippets.length).toBeGreaterThan(0);
|
|
772
904
|
|
|
773
905
|
let targetSnippet = snippets[0];
|
|
774
|
-
expect(targetSnippet.originalCode).toBe(
|
|
775
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
906
|
+
expect(targetSnippet.originalCode).toBe(`$"最终抗性: {resistReduce:F}\\n"`);
|
|
907
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("最终抗性: {0:F}\\n", resistReduce)`);
|
|
776
908
|
expect(targetSnippet.literals).toEqual(['最终抗性: {0:F}\\n']);
|
|
777
909
|
expect(targetSnippet.isChanged).toBe(true);
|
|
778
910
|
});
|
|
779
911
|
|
|
912
|
+
// 处理C#多行语句, 特别是包含 `\n` 的字符串
|
|
780
913
|
test('should handle multilne content17', () => {
|
|
781
914
|
const code = `
|
|
782
915
|
infoStr += $"aaa: {aa}\n" +
|
|
@@ -788,10 +921,10 @@ describe('CSharpStringExtractor', () => {
|
|
|
788
921
|
expect(snippets.length).toBeGreaterThan(0);
|
|
789
922
|
|
|
790
923
|
let targetSnippet = snippets[0];
|
|
791
|
-
expect(targetSnippet.originalCode).toBe(
|
|
792
|
-
$"bbb = {bb}"
|
|
793
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
794
|
-
Tr.Format("bbb = {0}", bb)
|
|
924
|
+
expect(targetSnippet.originalCode).toBe(`$"aaa: {aa}\n" +
|
|
925
|
+
$"bbb = {bb}"`);
|
|
926
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("aaa: {0}\n", aa) +
|
|
927
|
+
Tr.Format("bbb = {0}", bb)`);
|
|
795
928
|
expect(targetSnippet.literals).toEqual([
|
|
796
929
|
'aaa: {0}\n',
|
|
797
930
|
'bbb = {0}'
|
|
@@ -799,6 +932,7 @@ describe('CSharpStringExtractor', () => {
|
|
|
799
932
|
expect(targetSnippet.isChanged).toBe(true);
|
|
800
933
|
});
|
|
801
934
|
|
|
935
|
+
// 处理C#多行语句, 特别是包含 `\\n` 的内插字符串
|
|
802
936
|
test('should handle multilne content19', () => {
|
|
803
937
|
const code = `
|
|
804
938
|
infoStr += $"aaa: {aa}\\n" +
|
|
@@ -810,10 +944,10 @@ describe('CSharpStringExtractor', () => {
|
|
|
810
944
|
expect(snippets.length).toBeGreaterThan(0);
|
|
811
945
|
|
|
812
946
|
let targetSnippet = snippets[0];
|
|
813
|
-
expect(targetSnippet.originalCode).toBe(
|
|
814
|
-
$"bbb = {bb}"
|
|
815
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
816
|
-
Tr.Format("bbb = {0}", bb)
|
|
947
|
+
expect(targetSnippet.originalCode).toBe(`$"aaa: {aa}\\n" +
|
|
948
|
+
$"bbb = {bb}"`);
|
|
949
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("aaa: {0}\\n", aa) +
|
|
950
|
+
Tr.Format("bbb = {0}", bb)`);
|
|
817
951
|
expect(targetSnippet.literals).toEqual([
|
|
818
952
|
'aaa: {0}\\n',
|
|
819
953
|
'bbb = {0}'
|
|
@@ -821,6 +955,7 @@ describe('CSharpStringExtractor', () => {
|
|
|
821
955
|
expect(targetSnippet.isChanged).toBe(true);
|
|
822
956
|
});
|
|
823
957
|
|
|
958
|
+
// 处理C#中多行字符串拼接成的字符串表达式
|
|
824
959
|
test('should handle multilne content18', () => {
|
|
825
960
|
const code = `
|
|
826
961
|
infoStr += "伤害公式: \\n" +
|
|
@@ -838,22 +973,22 @@ describe('CSharpStringExtractor', () => {
|
|
|
838
973
|
expect(snippets.length).toBeGreaterThan(0);
|
|
839
974
|
|
|
840
975
|
let targetSnippet = snippets[0];
|
|
841
|
-
expect(targetSnippet.originalCode).toBe(`
|
|
976
|
+
expect(targetSnippet.originalCode).toBe(`"伤害公式: \\n" +
|
|
842
977
|
$"最终伤害[color={colorCode}][{(float)damageValue:F}][/color] = \\n" +
|
|
843
978
|
$"基础伤害[b][{baseValue:F}][/b] X \\n" +
|
|
844
979
|
$"暴击伤害加成[b][{damageInfo.CritDamageRatio:F}][/b] X \\n" +
|
|
845
980
|
$"最终伤害加成[b][{1 + damageInfo.FinalDamageRatio:F}][/b] X \\n" +
|
|
846
981
|
$"最终承伤加成[b][{1 + damageInfo.FinalInjuryRatio:F}][/b] / \\n" +
|
|
847
982
|
$"最终伤害减免[b][{1 + damageInfo.FinalDamageReduce:F}][/b] X \\n" +
|
|
848
|
-
$"抗性减免[b][{resistReduce:F}]"
|
|
849
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
983
|
+
$"抗性减免[b][{resistReduce:F}]"`);
|
|
984
|
+
expect(targetSnippet.convertedCode).toBe(`"伤害公式: \\n".TR() +
|
|
850
985
|
Tr.Format("最终伤害[color={0}][{1:F}][/color] = \\n", colorCode, (float)damageValue) +
|
|
851
986
|
Tr.Format("基础伤害[b][{0:F}][/b] X \\n", baseValue) +
|
|
852
987
|
Tr.Format("暴击伤害加成[b][{0:F}][/b] X \\n", damageInfo.CritDamageRatio) +
|
|
853
988
|
Tr.Format("最终伤害加成[b][{0:F}][/b] X \\n", 1 + damageInfo.FinalDamageRatio) +
|
|
854
989
|
Tr.Format("最终承伤加成[b][{0:F}][/b] / \\n", 1 + damageInfo.FinalInjuryRatio) +
|
|
855
990
|
Tr.Format("最终伤害减免[b][{0:F}][/b] X \\n", 1 + damageInfo.FinalDamageReduce) +
|
|
856
|
-
Tr.Format("抗性减免[b][{0:F}]", resistReduce)
|
|
991
|
+
Tr.Format("抗性减免[b][{0:F}]", resistReduce)`);
|
|
857
992
|
expect(targetSnippet.literals).toEqual([
|
|
858
993
|
'伤害公式: \\n',
|
|
859
994
|
'最终伤害[color={0}][{1:F}][/color] = \\n',
|
|
@@ -867,7 +1002,8 @@ describe('CSharpStringExtractor', () => {
|
|
|
867
1002
|
expect(targetSnippet.isChanged).toBe(true);
|
|
868
1003
|
});
|
|
869
1004
|
|
|
870
|
-
|
|
1005
|
+
// 处理C#中包含括号的内插字符串
|
|
1006
|
+
test('should handle bracket 1', () => {
|
|
871
1007
|
const code = `m_text_time.text = $"下一轮神兽出现倒计时: {Date.GetIntweerpolatedTime(ServerTimer.Instance.Time, _startGameStamp)}";`
|
|
872
1008
|
const snippets = extractor.extractStrings(code);
|
|
873
1009
|
|
|
@@ -875,15 +1011,16 @@ describe('CSharpStringExtractor', () => {
|
|
|
875
1011
|
expect(snippets.length).toBeGreaterThan(0);
|
|
876
1012
|
|
|
877
1013
|
let targetSnippet = snippets[0];
|
|
878
|
-
expect(targetSnippet.originalCode).toBe(
|
|
879
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1014
|
+
expect(targetSnippet.originalCode).toBe(`$"下一轮神兽出现倒计时: {Date.GetIntweerpolatedTime(ServerTimer.Instance.Time, _startGameStamp)}"`);
|
|
1015
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("下一轮神兽出现倒计时: {0}", Date.GetIntweerpolatedTime(ServerTimer.Instance.Time, _startGameStamp))`);
|
|
880
1016
|
expect(targetSnippet.literals).toEqual([
|
|
881
1017
|
'下一轮神兽出现倒计时: {0}'
|
|
882
1018
|
]);
|
|
883
1019
|
expect(targetSnippet.isChanged).toBe(true);
|
|
884
1020
|
});
|
|
885
1021
|
|
|
886
|
-
|
|
1022
|
+
// 处理C#中包含括号的内插字符串
|
|
1023
|
+
test('should handle bracket 2', () => {
|
|
887
1024
|
const code = `m_text_time.text = $"神兽离去时间: {Date.FeGetInterpolatedTime(ServerTimer.Instance.Time, _endGameStamp)}";`
|
|
888
1025
|
const snippets = extractor.extractStrings(code);
|
|
889
1026
|
|
|
@@ -891,15 +1028,16 @@ describe('CSharpStringExtractor', () => {
|
|
|
891
1028
|
expect(snippets.length).toBeGreaterThan(0);
|
|
892
1029
|
|
|
893
1030
|
let targetSnippet = snippets[0];
|
|
894
|
-
expect(targetSnippet.originalCode).toBe(
|
|
895
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1031
|
+
expect(targetSnippet.originalCode).toBe(`$"神兽离去时间: {Date.FeGetInterpolatedTime(ServerTimer.Instance.Time, _endGameStamp)}"`);
|
|
1032
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("神兽离去时间: {0}", Date.FeGetInterpolatedTime(ServerTimer.Instance.Time, _endGameStamp))`);
|
|
896
1033
|
expect(targetSnippet.literals).toEqual([
|
|
897
1034
|
'神兽离去时间: {0}'
|
|
898
1035
|
]);
|
|
899
1036
|
expect(targetSnippet.isChanged).toBe(true);
|
|
900
1037
|
});
|
|
901
1038
|
|
|
902
|
-
|
|
1039
|
+
// 处理C#中包含括号的内插字符串
|
|
1040
|
+
test('should handle bracket 3', () => {
|
|
903
1041
|
const code = `desc += $"剩余{ToGetInterpolatedTime(_cardPoolData.FinishTime * 1000, ServerTimer.Instance.Time)}";`
|
|
904
1042
|
const snippets = extractor.extractStrings(code);
|
|
905
1043
|
|
|
@@ -907,15 +1045,16 @@ describe('CSharpStringExtractor', () => {
|
|
|
907
1045
|
expect(snippets.length).toBeGreaterThan(0);
|
|
908
1046
|
|
|
909
1047
|
let targetSnippet = snippets[0];
|
|
910
|
-
expect(targetSnippet.originalCode).toBe(
|
|
911
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1048
|
+
expect(targetSnippet.originalCode).toBe(`$"剩余{ToGetInterpolatedTime(_cardPoolData.FinishTime * 1000, ServerTimer.Instance.Time)}"`);
|
|
1049
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("剩余{0}", ToGetInterpolatedTime(_cardPoolData.FinishTime * 1000, ServerTimer.Instance.Time))`);
|
|
912
1050
|
expect(targetSnippet.literals).toEqual([
|
|
913
1051
|
'剩余{0}'
|
|
914
1052
|
]);
|
|
915
1053
|
expect(targetSnippet.isChanged).toBe(true);
|
|
916
1054
|
});
|
|
917
1055
|
|
|
918
|
-
|
|
1056
|
+
// 处理C#中包含括号的内插字符串
|
|
1057
|
+
test('should handle bracket 4', () => {
|
|
919
1058
|
const code = `desc += $"剩余{ToGetInterpolatedTime(FF(_cardPoolData.FinishTime() * 1000, ServerTimer.Instance.Time()))}";`
|
|
920
1059
|
const snippets = extractor.extractStrings(code);
|
|
921
1060
|
|
|
@@ -923,14 +1062,15 @@ describe('CSharpStringExtractor', () => {
|
|
|
923
1062
|
expect(snippets.length).toBeGreaterThan(0);
|
|
924
1063
|
|
|
925
1064
|
let targetSnippet = snippets[0];
|
|
926
|
-
expect(targetSnippet.originalCode).toBe(
|
|
927
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1065
|
+
expect(targetSnippet.originalCode).toBe(`$"剩余{ToGetInterpolatedTime(FF(_cardPoolData.FinishTime() * 1000, ServerTimer.Instance.Time()))}"`);
|
|
1066
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("剩余{0}", ToGetInterpolatedTime(FF(_cardPoolData.FinishTime() * 1000, ServerTimer.Instance.Time())))`);
|
|
928
1067
|
expect(targetSnippet.literals).toEqual([
|
|
929
1068
|
'剩余{0}'
|
|
930
1069
|
]);
|
|
931
1070
|
expect(targetSnippet.isChanged).toBe(true);
|
|
932
1071
|
});
|
|
933
1072
|
|
|
1073
|
+
// 处理C#中包含`+=`符号的内插字符串
|
|
934
1074
|
test('should handle duplicate tr handle 1', () => {
|
|
935
1075
|
const code = `infoStr = $"+={colorCode}";`
|
|
936
1076
|
const snippets = extractor.extractStrings(code);
|
|
@@ -939,14 +1079,15 @@ describe('CSharpStringExtractor', () => {
|
|
|
939
1079
|
expect(snippets.length).toBeGreaterThan(0);
|
|
940
1080
|
|
|
941
1081
|
let targetSnippet = snippets[0];
|
|
942
|
-
expect(targetSnippet.originalCode).toBe(
|
|
943
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1082
|
+
expect(targetSnippet.originalCode).toBe(`$"+={colorCode}"`);
|
|
1083
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("+={0}", colorCode)`);
|
|
944
1084
|
expect(targetSnippet.literals).toEqual([
|
|
945
1085
|
'+={0}'
|
|
946
1086
|
]);
|
|
947
1087
|
expect(targetSnippet.isChanged).toBe(true);
|
|
948
1088
|
});
|
|
949
1089
|
|
|
1090
|
+
// 处理C# `+=` 形式的赋值语句后接 包含 `=` 符号的内插字符串
|
|
950
1091
|
test('should handle duplicate tr handle 2', () => {
|
|
951
1092
|
const code = `infoStr += $"={colorCode}";`
|
|
952
1093
|
const snippets = extractor.extractStrings(code);
|
|
@@ -955,14 +1096,15 @@ describe('CSharpStringExtractor', () => {
|
|
|
955
1096
|
expect(snippets.length).toBeGreaterThan(0);
|
|
956
1097
|
|
|
957
1098
|
let targetSnippet = snippets[0];
|
|
958
|
-
expect(targetSnippet.originalCode).toBe(
|
|
959
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1099
|
+
expect(targetSnippet.originalCode).toBe(`$"={colorCode}"`);
|
|
1100
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("={0}", colorCode)`);
|
|
960
1101
|
expect(targetSnippet.literals).toEqual([
|
|
961
1102
|
'={0}'
|
|
962
1103
|
]);
|
|
963
1104
|
expect(targetSnippet.isChanged).toBe(true);
|
|
964
1105
|
});
|
|
965
1106
|
|
|
1107
|
+
// 处理C# `+=` 形式的赋值语句后接 包含 `+=` 符号的内插字符串
|
|
966
1108
|
test('should handle duplicate tr handle 3', () => {
|
|
967
1109
|
const code = `infoStr += $"+={colorCode}";`
|
|
968
1110
|
const snippets = extractor.extractStrings(code);
|
|
@@ -971,14 +1113,15 @@ describe('CSharpStringExtractor', () => {
|
|
|
971
1113
|
expect(snippets.length).toBeGreaterThan(0);
|
|
972
1114
|
|
|
973
1115
|
let targetSnippet = snippets[0];
|
|
974
|
-
expect(targetSnippet.originalCode).toBe(
|
|
975
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1116
|
+
expect(targetSnippet.originalCode).toBe(`$"+={colorCode}"`);
|
|
1117
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("+={0}", colorCode)`);
|
|
976
1118
|
expect(targetSnippet.literals).toEqual([
|
|
977
1119
|
'+={0}'
|
|
978
1120
|
]);
|
|
979
1121
|
expect(targetSnippet.isChanged).toBe(true);
|
|
980
1122
|
});
|
|
981
|
-
|
|
1123
|
+
|
|
1124
|
+
// 处理C# `+=` 形式的赋值语句后接包含 `=`、`[`、`]`、`{`、`}`、`=` 等特殊符号的内插字符串
|
|
982
1125
|
test('should handle duplicate tr handle 4', () => {
|
|
983
1126
|
const code = `infoStr += $"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n";`
|
|
984
1127
|
const snippets = extractor.extractStrings(code);
|
|
@@ -987,14 +1130,15 @@ describe('CSharpStringExtractor', () => {
|
|
|
987
1130
|
expect(snippets.length).toBeGreaterThan(0);
|
|
988
1131
|
|
|
989
1132
|
let targetSnippet = snippets[0];
|
|
990
|
-
expect(targetSnippet.originalCode).toBe(
|
|
991
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1133
|
+
expect(targetSnippet.originalCode).toBe(`$"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n"`);
|
|
1134
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
992
1135
|
expect(targetSnippet.literals).toEqual([
|
|
993
1136
|
'伤害类型: [color={0}][b]{1}[/b][/color]\n'
|
|
994
1137
|
]);
|
|
995
1138
|
expect(targetSnippet.isChanged).toBe(true);
|
|
996
1139
|
});
|
|
997
1140
|
|
|
1141
|
+
// 处理C#中函数调用参数中包含普通字符串的情况, 函数参数需要拆分, 逐个参数捕获
|
|
998
1142
|
test('should handle para 1', () => {
|
|
999
1143
|
const code = `SetData("等级", level + 1);`
|
|
1000
1144
|
const snippets = extractor.extractStrings(code);
|
|
@@ -1003,14 +1147,16 @@ describe('CSharpStringExtractor', () => {
|
|
|
1003
1147
|
expect(snippets.length).toBeGreaterThan(0);
|
|
1004
1148
|
|
|
1005
1149
|
let targetSnippet = snippets[0];
|
|
1006
|
-
|
|
1007
|
-
expect(targetSnippet.
|
|
1150
|
+
// 函数参数需要拆分, 逐个参数捕获
|
|
1151
|
+
expect(targetSnippet.originalCode).toBe(`"等级"`);
|
|
1152
|
+
expect(targetSnippet.convertedCode).toBe(`"等级"`);
|
|
1008
1153
|
expect(targetSnippet.literals).toEqual([
|
|
1009
1154
|
"等级"
|
|
1010
1155
|
]);
|
|
1011
1156
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1012
1157
|
});
|
|
1013
1158
|
|
|
1159
|
+
// 处理C#中函数调用参数中包含普通字符串的情况
|
|
1014
1160
|
test('should handle para 2', () => {
|
|
1015
1161
|
const code = `bbb.Func2("等级", level, level + 1, false, isMax);`
|
|
1016
1162
|
const snippets = extractor.extractStrings(code);
|
|
@@ -1019,11 +1165,1330 @@ describe('CSharpStringExtractor', () => {
|
|
|
1019
1165
|
expect(snippets.length).toBeGreaterThan(0);
|
|
1020
1166
|
|
|
1021
1167
|
let targetSnippet = snippets[0];
|
|
1022
|
-
expect(targetSnippet.originalCode).toBe(`
|
|
1023
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1168
|
+
expect(targetSnippet.originalCode).toBe(`"等级"`);
|
|
1169
|
+
expect(targetSnippet.convertedCode).toBe(`"等级"`);
|
|
1024
1170
|
expect(targetSnippet.literals).toEqual([
|
|
1025
1171
|
"等级"
|
|
1026
1172
|
]);
|
|
1027
1173
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1028
1174
|
});
|
|
1175
|
+
|
|
1176
|
+
// 处理C#中switch语句中包含普通字符串的情况
|
|
1177
|
+
test('should handle switch 1', () => {
|
|
1178
|
+
const code = `
|
|
1179
|
+
switch(condition){
|
|
1180
|
+
default:
|
|
1181
|
+
Log.Warning("实时更新自:" + rankData.Type);
|
|
1182
|
+
break;
|
|
1183
|
+
}`
|
|
1184
|
+
const snippets = extractor.extractStrings(code);
|
|
1185
|
+
|
|
1186
|
+
// 验证提取的片段数量
|
|
1187
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1188
|
+
|
|
1189
|
+
let targetSnippet = snippets[0];
|
|
1190
|
+
expect(targetSnippet.originalCode).toBe(`"实时更新自:" + rankData.Type`);
|
|
1191
|
+
// 普通函数参数不需要追加 `.TR()`, 除非包含由 `+` 符号连接字符串等的情况
|
|
1192
|
+
expect(targetSnippet.convertedCode).toBe(`"实时更新自:" + rankData.Type`);
|
|
1193
|
+
expect(targetSnippet.literals).toEqual([
|
|
1194
|
+
"实时更新自:"
|
|
1195
|
+
]);
|
|
1196
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1199
|
+
// 处理C#中switch语句中包含普通字符串的情况
|
|
1200
|
+
test('should handle switch 2', () => {
|
|
1201
|
+
const code = `
|
|
1202
|
+
switch(kwjkwlje){
|
|
1203
|
+
case (int)RANK_TYPE.天梯段位:
|
|
1204
|
+
Debug.Log1("jkwhfehwfjkh:" + rank2Data.T4zype);
|
|
1205
|
+
break;
|
|
1206
|
+
}`
|
|
1207
|
+
const snippets = extractor.extractStrings(code);
|
|
1208
|
+
|
|
1209
|
+
// 验证提取的片段数量, switch 语句中包含普通字符串的情况
|
|
1210
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1211
|
+
|
|
1212
|
+
let targetSnippet = snippets[0];
|
|
1213
|
+
expect(targetSnippet.originalCode).toBe(`"jkwhfehwfjkh:" + rank2Data.T4zype`);
|
|
1214
|
+
expect(targetSnippet.convertedCode).toBe(`"jkwhfehwfjkh:" + rank2Data.T4zype`);
|
|
1215
|
+
expect(targetSnippet.literals).toEqual([
|
|
1216
|
+
"jkwhfehwfjkh:"
|
|
1217
|
+
]);
|
|
1218
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
// 处理C#中switch语句中包含普通字符串的情况
|
|
1222
|
+
test('should handle switch 3', () => {
|
|
1223
|
+
const code = `
|
|
1224
|
+
switch(lkw){
|
|
1225
|
+
case V434:
|
|
1226
|
+
{
|
|
1227
|
+
Action2("wegwfw:" + varnws);
|
|
1228
|
+
break;
|
|
1229
|
+
}
|
|
1230
|
+
}`
|
|
1231
|
+
const snippets = extractor.extractStrings(code);
|
|
1232
|
+
|
|
1233
|
+
// 验证提取的片段数量
|
|
1234
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1235
|
+
|
|
1236
|
+
let targetSnippet = snippets[0];
|
|
1237
|
+
expect(targetSnippet.originalCode).toBe(`"wegwfw:" + varnws`);
|
|
1238
|
+
expect(targetSnippet.convertedCode).toBe(`"wegwfw:" + varnws`);
|
|
1239
|
+
expect(targetSnippet.literals).toEqual([
|
|
1240
|
+
"wegwfw:"
|
|
1241
|
+
]);
|
|
1242
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1243
|
+
});
|
|
1244
|
+
|
|
1245
|
+
// 处理C#中switch语句中包含普通字符串的情况
|
|
1246
|
+
test('should handle switch 4', () => {
|
|
1247
|
+
const code = `
|
|
1248
|
+
case V434:
|
|
1249
|
+
Action2("wegwfw:" + varnws);
|
|
1250
|
+
break;`
|
|
1251
|
+
const snippets = extractor.extractStrings(code);
|
|
1252
|
+
|
|
1253
|
+
// 验证提取的片段数量
|
|
1254
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1255
|
+
|
|
1256
|
+
let targetSnippet = snippets[0];
|
|
1257
|
+
expect(targetSnippet.originalCode).toBe(`"wegwfw:" + varnws`);
|
|
1258
|
+
expect(targetSnippet.convertedCode).toBe(`"wegwfw:" + varnws`);
|
|
1259
|
+
expect(targetSnippet.literals).toEqual([
|
|
1260
|
+
"wegwfw:"
|
|
1261
|
+
]);
|
|
1262
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1263
|
+
});
|
|
1264
|
+
|
|
1265
|
+
// 处理 C#内容中存在多个相同的包含字符串的语句时, 要每个都提取出来
|
|
1266
|
+
test('should handle lost 1', () => {
|
|
1267
|
+
const code = readFileSync('./test/KeeperDialog.cs', 'utf8');
|
|
1268
|
+
const snippets = extractor.extractStrings(code);
|
|
1269
|
+
|
|
1270
|
+
let targetSnippet = snippets[3];
|
|
1271
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"已购买";
|
|
1272
|
+
m_btn_buy.enabled = false;
|
|
1273
|
+
|
|
1274
|
+
//购买后自动启用`));
|
|
1275
|
+
expect(targetSnippet.originalCode).toBe(`"已购买"`);
|
|
1276
|
+
expect(targetSnippet.convertedCode).toBe(`"已购买".TR()`);
|
|
1277
|
+
expect(targetSnippet.literals).toEqual([
|
|
1278
|
+
"已购买"
|
|
1279
|
+
]);
|
|
1280
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1281
|
+
|
|
1282
|
+
// 验证提取的片段数量
|
|
1283
|
+
expect(snippets.length).toBeGreaterThanOrEqual(5)
|
|
1284
|
+
});
|
|
1285
|
+
|
|
1286
|
+
// 字符串中包含 `)` 符号时, 也需要捕获该字符串
|
|
1287
|
+
test('should handle lost 2', () => {
|
|
1288
|
+
const code = `m_text_runeSlot.text = Tr.Format(")", _sutraCardData.Card.RuneOpenCount);`;
|
|
1289
|
+
const snippets = extractor.extractStrings(code);
|
|
1290
|
+
|
|
1291
|
+
let targetSnippet = snippets[0];
|
|
1292
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format(")", _sutraCardData.Card.RuneOpenCount)`));
|
|
1293
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format(")", _sutraCardData.Card.RuneOpenCount)`);
|
|
1294
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format(")", _sutraCardData.Card.RuneOpenCount)`);
|
|
1295
|
+
// 字符串中包含 `)` 符号时, 也需要捕获该字符串
|
|
1296
|
+
expect(targetSnippet.literals).toEqual([
|
|
1297
|
+
')'
|
|
1298
|
+
]);
|
|
1299
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1300
|
+
|
|
1301
|
+
});
|
|
1302
|
+
|
|
1303
|
+
// 处理 C#内容时, 需要匹配出包含 `(` 符号的字符串表达式
|
|
1304
|
+
test('should handle lost 3', () => {
|
|
1305
|
+
const code = `m_text_runeSlot.text = ")";`;
|
|
1306
|
+
const snippets = extractor.extractStrings(code);
|
|
1307
|
+
|
|
1308
|
+
let targetSnippet = snippets[0];
|
|
1309
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`")"`));
|
|
1310
|
+
expect(targetSnippet.originalCode).toBe(`")"`);
|
|
1311
|
+
expect(targetSnippet.convertedCode).toBe(`")".TR()`);
|
|
1312
|
+
expect(targetSnippet.literals).toEqual([
|
|
1313
|
+
')'
|
|
1314
|
+
]);
|
|
1315
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1316
|
+
|
|
1317
|
+
});
|
|
1318
|
+
|
|
1319
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1320
|
+
test('should handle return statement 1', () => {
|
|
1321
|
+
const code = `return "参数错误";`;
|
|
1322
|
+
const snippets = extractor.extractStrings(code);
|
|
1323
|
+
|
|
1324
|
+
let targetSnippet = snippets[0];
|
|
1325
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"参数错误"`));
|
|
1326
|
+
expect(targetSnippet.originalCode).toBe(`"参数错误"`);
|
|
1327
|
+
expect(targetSnippet.convertedCode).toBe(`"参数错误"`);
|
|
1328
|
+
expect(targetSnippet.literals).toEqual([
|
|
1329
|
+
'参数错误'
|
|
1330
|
+
]);
|
|
1331
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1332
|
+
|
|
1333
|
+
});
|
|
1334
|
+
|
|
1335
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1336
|
+
test('should handle return statement 2', () => {
|
|
1337
|
+
const code = `return "";`;
|
|
1338
|
+
const snippets = extractor.extractStrings(code);
|
|
1339
|
+
|
|
1340
|
+
let targetSnippet = snippets[0];
|
|
1341
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`""`));
|
|
1342
|
+
expect(targetSnippet.originalCode).toBe(`""`);
|
|
1343
|
+
expect(targetSnippet.convertedCode).toBe(`""`);
|
|
1344
|
+
expect(targetSnippet.literals).toEqual([
|
|
1345
|
+
''
|
|
1346
|
+
]);
|
|
1347
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1348
|
+
|
|
1349
|
+
});
|
|
1350
|
+
|
|
1351
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1352
|
+
test('should handle return statement 3', () => {
|
|
1353
|
+
const code = `return $"";`;
|
|
1354
|
+
const snippets = extractor.extractStrings(code);
|
|
1355
|
+
|
|
1356
|
+
let targetSnippet = snippets[0];
|
|
1357
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$""`));
|
|
1358
|
+
expect(targetSnippet.originalCode).toBe(`$""`);
|
|
1359
|
+
expect(targetSnippet.convertedCode).toBe(`$""`);
|
|
1360
|
+
expect(targetSnippet.literals).toEqual([
|
|
1361
|
+
''
|
|
1362
|
+
]);
|
|
1363
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1364
|
+
|
|
1365
|
+
});
|
|
1366
|
+
|
|
1367
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1368
|
+
test('should handle return statement 4', () => {
|
|
1369
|
+
const code = `return $"fwefwe";`;
|
|
1370
|
+
const snippets = extractor.extractStrings(code);
|
|
1371
|
+
|
|
1372
|
+
let targetSnippet = snippets[0];
|
|
1373
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"fwefwe"`));
|
|
1374
|
+
expect(targetSnippet.originalCode).toBe(`$"fwefwe"`);
|
|
1375
|
+
expect(targetSnippet.convertedCode).toBe(`$"fwefwe"`);
|
|
1376
|
+
expect(targetSnippet.literals).toEqual([
|
|
1377
|
+
'fwefwe'
|
|
1378
|
+
]);
|
|
1379
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1380
|
+
|
|
1381
|
+
});
|
|
1382
|
+
|
|
1383
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1384
|
+
test('should handle return statement 5', () => {
|
|
1385
|
+
const code = `return $"wefwf{fwef}";`;
|
|
1386
|
+
const snippets = extractor.extractStrings(code);
|
|
1387
|
+
|
|
1388
|
+
let targetSnippet = snippets[0];
|
|
1389
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"wefwf{fwef}"`));
|
|
1390
|
+
expect(targetSnippet.originalCode).toBe(`$"wefwf{fwef}"`);
|
|
1391
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("wefwf{0}", fwef)`);
|
|
1392
|
+
expect(targetSnippet.literals).toEqual([
|
|
1393
|
+
'wefwf{0}'
|
|
1394
|
+
]);
|
|
1395
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1396
|
+
|
|
1397
|
+
});
|
|
1398
|
+
|
|
1399
|
+
// 测试处理C#字符串表达式中包含各种特殊字符的情况
|
|
1400
|
+
test('should handle special characters in string expression 1', () => {
|
|
1401
|
+
const code = `return "abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\";`;
|
|
1402
|
+
const snippets = extractor.extractStrings(code);
|
|
1403
|
+
|
|
1404
|
+
let targetSnippet = snippets[0];
|
|
1405
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\"`));
|
|
1406
|
+
expect(targetSnippet.originalCode).toBe(`"abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\"`);
|
|
1407
|
+
expect(targetSnippet.convertedCode).toBe(`"abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\"`);
|
|
1408
|
+
expect(targetSnippet.literals).toEqual([
|
|
1409
|
+
'abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\'
|
|
1410
|
+
]);
|
|
1411
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1412
|
+
});
|
|
1413
|
+
|
|
1414
|
+
// 测试处理在C#类成员初始赋值语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1415
|
+
test('should handle member initial assignment', () => {
|
|
1416
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1417
|
+
const snippets = extractor.extractStrings(code);
|
|
1418
|
+
{
|
|
1419
|
+
let targetSnippet = snippets[0];
|
|
1420
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"\\\\"`));
|
|
1421
|
+
expect(targetSnippet.originalCode).toBe(`"\\\\"`);
|
|
1422
|
+
expect(targetSnippet.convertedCode).toBe(`"\\\\"`);
|
|
1423
|
+
expect(targetSnippet.literals).toEqual([
|
|
1424
|
+
'\\\\'
|
|
1425
|
+
]);
|
|
1426
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1427
|
+
}
|
|
1428
|
+
{
|
|
1429
|
+
let targetSnippet = snippets[1];
|
|
1430
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"\\n"`));
|
|
1431
|
+
expect(targetSnippet.originalCode).toBe(`"\\n"`);
|
|
1432
|
+
expect(targetSnippet.convertedCode).toBe(`"\\n"`);
|
|
1433
|
+
expect(targetSnippet.literals).toEqual([
|
|
1434
|
+
'\\n'
|
|
1435
|
+
]);
|
|
1436
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1437
|
+
}
|
|
1438
|
+
{
|
|
1439
|
+
let targetSnippet = snippets[2];
|
|
1440
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"\\t"`));
|
|
1441
|
+
expect(targetSnippet.originalCode).toBe(`$"\\t"`);
|
|
1442
|
+
expect(targetSnippet.convertedCode).toBe(`$"\\t"`);
|
|
1443
|
+
expect(targetSnippet.literals).toEqual([
|
|
1444
|
+
'\\t'
|
|
1445
|
+
]);
|
|
1446
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
|
|
1450
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1451
|
+
test('should handle special characters in string expression 3', () => {
|
|
1452
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1453
|
+
const snippets = extractor.extractStrings(code);
|
|
1454
|
+
{
|
|
1455
|
+
let targetSnippet = snippets[3];
|
|
1456
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1457
|
+
expect(targetSnippet.originalCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1458
|
+
expect(targetSnippet.convertedCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1459
|
+
expect(targetSnippet.literals).toEqual([
|
|
1460
|
+
'1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1461
|
+
]);
|
|
1462
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1463
|
+
}
|
|
1464
|
+
{
|
|
1465
|
+
let targetSnippet = snippets[4];
|
|
1466
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1467
|
+
expect(targetSnippet.originalCode).toBe(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1468
|
+
expect(targetSnippet.convertedCode).toBe(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1469
|
+
expect(targetSnippet.literals).toEqual([
|
|
1470
|
+
'2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1471
|
+
]);
|
|
1472
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1473
|
+
}
|
|
1474
|
+
{
|
|
1475
|
+
let targetSnippet = snippets[6];
|
|
1476
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1477
|
+
expect(targetSnippet.originalCode).toBe(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1478
|
+
expect(targetSnippet.convertedCode).toBe(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1479
|
+
expect(targetSnippet.literals).toEqual([
|
|
1480
|
+
'4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1481
|
+
]);
|
|
1482
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1483
|
+
}
|
|
1484
|
+
});
|
|
1485
|
+
|
|
1486
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1487
|
+
test('should handle special characters in string expression 3.1', () => {
|
|
1488
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1489
|
+
const snippets = extractor.extractStrings(code);
|
|
1490
|
+
{
|
|
1491
|
+
let targetSnippet = snippets[3];
|
|
1492
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1493
|
+
expect(targetSnippet.originalCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1494
|
+
expect(targetSnippet.convertedCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1495
|
+
expect(targetSnippet.literals).toEqual([
|
|
1496
|
+
'1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1497
|
+
]);
|
|
1498
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
|
|
1502
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1503
|
+
test('should handle special characters in string expression of return sentence', () => {
|
|
1504
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1505
|
+
const snippets = extractor.extractStrings(code);
|
|
1506
|
+
{
|
|
1507
|
+
let targetSnippet = snippets[7];
|
|
1508
|
+
// 需要统一匹配 `return` 语句中的字符串表达式
|
|
1509
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1510
|
+
expect(targetSnippet.originalCode).toBe(`"5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1511
|
+
expect(targetSnippet.convertedCode).toBe(`"5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1512
|
+
expect(targetSnippet.literals).toEqual([
|
|
1513
|
+
'5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1514
|
+
]);
|
|
1515
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1516
|
+
}
|
|
1517
|
+
});
|
|
1518
|
+
|
|
1519
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1520
|
+
test('should handle special characters in string expression 3.2', () => {
|
|
1521
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1522
|
+
const snippets = extractor.extractStrings(code);
|
|
1523
|
+
{
|
|
1524
|
+
let targetSnippet = snippets[8];
|
|
1525
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1526
|
+
expect(targetSnippet.originalCode).toBe(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1527
|
+
expect(targetSnippet.convertedCode).toBe(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1528
|
+
expect(targetSnippet.literals).toEqual([
|
|
1529
|
+
'6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1530
|
+
]);
|
|
1531
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1532
|
+
}
|
|
1533
|
+
{
|
|
1534
|
+
let targetSnippet = snippets[9];
|
|
1535
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1536
|
+
expect(targetSnippet.originalCode).toBe(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1537
|
+
expect(targetSnippet.convertedCode).toBe(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1538
|
+
expect(targetSnippet.literals).toEqual([
|
|
1539
|
+
'7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1540
|
+
]);
|
|
1541
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1542
|
+
}
|
|
1543
|
+
});
|
|
1544
|
+
|
|
1545
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1546
|
+
test('should handle special characters in string expression 4', () => {
|
|
1547
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1548
|
+
const snippets = extractor.extractStrings(code);
|
|
1549
|
+
{
|
|
1550
|
+
let targetSnippet = snippets[5];
|
|
1551
|
+
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1552
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"3. {wef}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1553
|
+
expect(targetSnippet.originalCode).toBe(`$"3. {wef}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1554
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("3. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wef)`);
|
|
1555
|
+
expect(targetSnippet.literals).toEqual([
|
|
1556
|
+
'3. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1557
|
+
]);
|
|
1558
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1559
|
+
}
|
|
1560
|
+
});
|
|
1561
|
+
|
|
1562
|
+
// 测试处理在C#各种形式语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#内插字符串边界识别和捕获
|
|
1563
|
+
test('should handle special characters in string expression 5', () => {
|
|
1564
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1565
|
+
const snippets = extractor.extractStrings(code);
|
|
1566
|
+
{
|
|
1567
|
+
let targetSnippet = snippets[10];
|
|
1568
|
+
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1569
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"8. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1570
|
+
expect(targetSnippet.originalCode).toBe(`$"8. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1571
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("8. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1572
|
+
expect(targetSnippet.literals).toEqual([
|
|
1573
|
+
'8. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1574
|
+
]);
|
|
1575
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1576
|
+
}
|
|
1577
|
+
});
|
|
1578
|
+
|
|
1579
|
+
// 测试处理在C#各种形式语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#内插字符串边界识别和捕获
|
|
1580
|
+
test('should handle special characters in string expression 6', () => {
|
|
1581
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1582
|
+
const snippets = extractor.extractStrings(code);
|
|
1583
|
+
{
|
|
1584
|
+
let targetSnippet = snippets[11];
|
|
1585
|
+
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1586
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"9. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1587
|
+
expect(targetSnippet.originalCode).toBe(`$"9. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1588
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("9. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1589
|
+
expect(targetSnippet.literals).toEqual([
|
|
1590
|
+
'9. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1591
|
+
]);
|
|
1592
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1593
|
+
}
|
|
1594
|
+
});
|
|
1595
|
+
|
|
1596
|
+
// 测试处理在C#各种形式语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#内插字符串边界识别和捕获
|
|
1597
|
+
test('should handle special characters in string expression 7', () => {
|
|
1598
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1599
|
+
const snippets = extractor.extractStrings(code);
|
|
1600
|
+
{
|
|
1601
|
+
let targetSnippet = snippets[12];
|
|
1602
|
+
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1603
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"10. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1604
|
+
expect(targetSnippet.originalCode).toBe(`$"10. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1605
|
+
// 需要统一匹配 `return` 语句中的字符串表达式
|
|
1606
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("10. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1607
|
+
expect(targetSnippet.literals).toEqual([
|
|
1608
|
+
'10. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1609
|
+
]);
|
|
1610
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1611
|
+
}
|
|
1612
|
+
});
|
|
1613
|
+
|
|
1614
|
+
test('should handle optional value assignment', () => {
|
|
1615
|
+
const code = `m_text_otherName.text = battleModel.TeammatePlayerData?.Name ?? "";`;
|
|
1616
|
+
const snippets = extractor.extractStrings(code);
|
|
1617
|
+
{
|
|
1618
|
+
let targetSnippet = snippets[0];
|
|
1619
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`battleModel.TeammatePlayerData?.Name ?? ""`));
|
|
1620
|
+
expect(targetSnippet.originalCode).toBe(`battleModel.TeammatePlayerData?.Name ?? ""`);
|
|
1621
|
+
expect(targetSnippet.convertedCode).toBe(`battleModel.TeammatePlayerData?.Name ?? "".TR()`);
|
|
1622
|
+
expect(targetSnippet.literals).toEqual([
|
|
1623
|
+
''
|
|
1624
|
+
]);
|
|
1625
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1626
|
+
}
|
|
1627
|
+
});
|
|
1628
|
+
|
|
1629
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1630
|
+
test('should handle string in comment 1', () => {
|
|
1631
|
+
const code = `
|
|
1632
|
+
protected override void OnShow(object param)
|
|
1633
|
+
{
|
|
1634
|
+
// Log.Info("AAA:ChooseSutraLayer显示1");
|
|
1635
|
+
base.OnShow(param);
|
|
1636
|
+
}`;
|
|
1637
|
+
const snippets = extractor.extractStrings(code);
|
|
1638
|
+
{
|
|
1639
|
+
let targetSnippet = snippets[0];
|
|
1640
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"AAA:ChooseSutraLayer显示1"`));
|
|
1641
|
+
expect(targetSnippet.originalCode).toBe(`"AAA:ChooseSutraLayer显示1"`);
|
|
1642
|
+
expect(targetSnippet.convertedCode).toBe(`"AAA:ChooseSutraLayer显示1"`);
|
|
1643
|
+
expect(targetSnippet.literals).toEqual([
|
|
1644
|
+
'AAA:ChooseSutraLayer显示1'
|
|
1645
|
+
]);
|
|
1646
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1647
|
+
}
|
|
1648
|
+
});
|
|
1649
|
+
|
|
1650
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1651
|
+
test('should handle string in comment 2', () => {
|
|
1652
|
+
const code = `
|
|
1653
|
+
protected override void OnShow(object param)
|
|
1654
|
+
{
|
|
1655
|
+
// Log.Info($"BBB:Jowikwf");
|
|
1656
|
+
base.OnShow(param);
|
|
1657
|
+
}`;
|
|
1658
|
+
const snippets = extractor.extractStrings(code);
|
|
1659
|
+
{
|
|
1660
|
+
let targetSnippet = snippets[0];
|
|
1661
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"BBB:Jowikwf"`));
|
|
1662
|
+
expect(targetSnippet.originalCode).toBe(`$"BBB:Jowikwf"`);
|
|
1663
|
+
expect(targetSnippet.convertedCode).toBe(`$"BBB:Jowikwf"`);
|
|
1664
|
+
expect(targetSnippet.literals).toEqual([
|
|
1665
|
+
'BBB:Jowikwf'
|
|
1666
|
+
]);
|
|
1667
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1668
|
+
}
|
|
1669
|
+
});
|
|
1670
|
+
|
|
1671
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1672
|
+
test('should handle string in comment 3', () => {
|
|
1673
|
+
const code = `
|
|
1674
|
+
protected override void OnShow(object param)
|
|
1675
|
+
{
|
|
1676
|
+
// Log.Info($"BBB:{wlek}Jowikwf");
|
|
1677
|
+
base.OnShow(param);
|
|
1678
|
+
}`;
|
|
1679
|
+
const snippets = extractor.extractStrings(code);
|
|
1680
|
+
{
|
|
1681
|
+
let targetSnippet = snippets[0];
|
|
1682
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"BBB:{wlek}Jowikwf"`));
|
|
1683
|
+
expect(targetSnippet.originalCode).toBe(`$"BBB:{wlek}Jowikwf"`);
|
|
1684
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("BBB:{0}Jowikwf", wlek)`);
|
|
1685
|
+
expect(targetSnippet.literals).toEqual([
|
|
1686
|
+
'BBB:{0}Jowikwf'
|
|
1687
|
+
]);
|
|
1688
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1689
|
+
}
|
|
1690
|
+
});
|
|
1691
|
+
|
|
1692
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1693
|
+
test('should handle string in comment 4', () => {
|
|
1694
|
+
const code = `
|
|
1695
|
+
protected override void OnShow(object param)
|
|
1696
|
+
{
|
|
1697
|
+
// Log.Info("{}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\");
|
|
1698
|
+
base.OnShow(param);
|
|
1699
|
+
}`;
|
|
1700
|
+
const snippets = extractor.extractStrings(code);
|
|
1701
|
+
{
|
|
1702
|
+
let targetSnippet = snippets[0];
|
|
1703
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"{}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1704
|
+
expect(targetSnippet.originalCode).toBe(`"{}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1705
|
+
expect(targetSnippet.convertedCode).toBe(`"{}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1706
|
+
expect(targetSnippet.literals).toEqual([
|
|
1707
|
+
'{}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1708
|
+
]);
|
|
1709
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1710
|
+
}
|
|
1711
|
+
});
|
|
1712
|
+
|
|
1713
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1714
|
+
test('should handle string in comment 5', () => {
|
|
1715
|
+
const code = `
|
|
1716
|
+
protected override void OnShow(object param)
|
|
1717
|
+
{
|
|
1718
|
+
// Log.Info($"{wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\");
|
|
1719
|
+
base.OnShow(param);
|
|
1720
|
+
}`;
|
|
1721
|
+
const snippets = extractor.extractStrings(code);
|
|
1722
|
+
{
|
|
1723
|
+
let targetSnippet = snippets[0];
|
|
1724
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"{wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1725
|
+
expect(targetSnippet.originalCode).toBe(`$"{wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1726
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1727
|
+
expect(targetSnippet.literals).toEqual([
|
|
1728
|
+
'{0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1729
|
+
]);
|
|
1730
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1731
|
+
}
|
|
1732
|
+
});
|
|
1733
|
+
|
|
1734
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1735
|
+
test('should handle complex string 1', () => {
|
|
1736
|
+
const code = `
|
|
1737
|
+
infoStr += $"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n";
|
|
1738
|
+
infoStr += $"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n";
|
|
1739
|
+
`;
|
|
1740
|
+
const snippets = extractor.extractStrings(code);
|
|
1741
|
+
{
|
|
1742
|
+
let targetSnippet = snippets[0];
|
|
1743
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n"`));
|
|
1744
|
+
expect(targetSnippet.originalCode).toBe(`$"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n"`);
|
|
1745
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
1746
|
+
expect(targetSnippet.literals).toEqual([
|
|
1747
|
+
'伤害类型: [color={0}][b]{1}[/b][/color]\n'
|
|
1748
|
+
]);
|
|
1749
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1750
|
+
}
|
|
1751
|
+
});
|
|
1752
|
+
|
|
1753
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1754
|
+
test('should handle complex string 2', () => {
|
|
1755
|
+
const code = `
|
|
1756
|
+
infoStr += Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType);
|
|
1757
|
+
infoStr += $"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n";
|
|
1758
|
+
`;
|
|
1759
|
+
const snippets = extractor.extractStrings(code);
|
|
1760
|
+
{
|
|
1761
|
+
let targetSnippet = snippets[0];
|
|
1762
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`));
|
|
1763
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
1764
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
1765
|
+
expect(targetSnippet.literals).toEqual([
|
|
1766
|
+
'伤害类型: [color={0}][b]{1}[/b][/color]\n'
|
|
1767
|
+
]);
|
|
1768
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1769
|
+
}
|
|
1770
|
+
});
|
|
1771
|
+
|
|
1772
|
+
// 正确处理C# 字符串表达式中递归内嵌字符串表达式的情况: 需要正确转换内插字符串格式
|
|
1773
|
+
test('should handle fix interpolated string nested literals', () => {
|
|
1774
|
+
const code = `infoStr += $"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n";`;
|
|
1775
|
+
const snippets = extractor.extractStrings(code);
|
|
1776
|
+
{
|
|
1777
|
+
let targetSnippet = snippets[0];
|
|
1778
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n"`));
|
|
1779
|
+
expect(targetSnippet.originalCode).toBe(`$"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n"`);
|
|
1780
|
+
// 需要正确转换内插字符串格式
|
|
1781
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("是否暴击: [b]{0}[/b]\n", (_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否"))`);
|
|
1782
|
+
expect(targetSnippet.literals).toEqual([
|
|
1783
|
+
'是否暴击: [b]{0}[/b]\n'
|
|
1784
|
+
]);
|
|
1785
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1786
|
+
}
|
|
1787
|
+
});
|
|
1788
|
+
|
|
1789
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1790
|
+
test('should handle complex string with optional value 3', () => {
|
|
1791
|
+
const code = `
|
|
1792
|
+
else if (battleModel.CurGameType == BattleModel.GameType.Teamwork)
|
|
1793
|
+
{
|
|
1794
|
+
//合作模式显示队友名称
|
|
1795
|
+
m_text_otherName.text = battleModel.TeammatePlayerData?.Name ?? "";
|
|
1796
|
+
}
|
|
1797
|
+
`;
|
|
1798
|
+
const snippets = extractor.extractStrings(code);
|
|
1799
|
+
{
|
|
1800
|
+
let targetSnippet = snippets[0];
|
|
1801
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`battleModel.TeammatePlayerData?.Name ?? ""`));
|
|
1802
|
+
expect(targetSnippet.originalCode).toBe(`battleModel.TeammatePlayerData?.Name ?? ""`);
|
|
1803
|
+
expect(targetSnippet.convertedCode).toBe(`battleModel.TeammatePlayerData?.Name ?? "".TR()`);
|
|
1804
|
+
expect(targetSnippet.literals).toEqual([
|
|
1805
|
+
''
|
|
1806
|
+
]);
|
|
1807
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1808
|
+
}
|
|
1809
|
+
});
|
|
1810
|
+
|
|
1811
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1812
|
+
test('should handle complex string 4', () => {
|
|
1813
|
+
const code = `
|
|
1814
|
+
private void OnBtnIaa(EventContext context)
|
|
1815
|
+
{
|
|
1816
|
+
var iaaConfig = IAAConfigTable.GetConfigById((int)IAAId.境界失败_加速冷却);
|
|
1817
|
+
if (iaaConfig == null)
|
|
1818
|
+
{
|
|
1819
|
+
return;
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
string des = $"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟";
|
|
1823
|
+
this.GetModel<IAAModel>().ShowAdWithDialog(IAAId.境界失败_加速冷却, "加速时间", des, null);
|
|
1824
|
+
}
|
|
1825
|
+
`;
|
|
1826
|
+
const snippets = extractor.extractStrings(code);
|
|
1827
|
+
{
|
|
1828
|
+
let targetSnippet = snippets[0];
|
|
1829
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟"`));
|
|
1830
|
+
expect(targetSnippet.originalCode).toBe(`$"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟"`);
|
|
1831
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("观看视频后\n等待时间减少{0}分钟", iaaConfig.EffectValue / 60)`);
|
|
1832
|
+
expect(targetSnippet.literals).toEqual([
|
|
1833
|
+
'观看视频后\n等待时间减少{0}分钟'
|
|
1834
|
+
]);
|
|
1835
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1836
|
+
}
|
|
1837
|
+
});
|
|
1838
|
+
|
|
1839
|
+
// 需要正确识别函数调用参数中每个参数的边界, 并识别每个参数中的字符串表达式
|
|
1840
|
+
test('should handle strings in function call arguments', () => {
|
|
1841
|
+
const code = `
|
|
1842
|
+
private void OnBtnIaa(EventContext context)
|
|
1843
|
+
{
|
|
1844
|
+
var iaaConfig = IAAConfigTable.GetConfigById((int)IAAId.境界失败_加速冷却);
|
|
1845
|
+
if (iaaConfig == null)
|
|
1846
|
+
{
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
string des = $"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟";
|
|
1851
|
+
this.GetModel<IAAModel>().ShowAdWithDialog(IAAId.境界失败_加速冷却, "加速时间", des, null);
|
|
1852
|
+
}
|
|
1853
|
+
`;
|
|
1854
|
+
const snippets = extractor.extractStrings(code);
|
|
1855
|
+
{
|
|
1856
|
+
let targetSnippet = snippets[1];
|
|
1857
|
+
// 需要正确识别函数调用参数中每个参数的边界, 并识别每个参数中的字符串表达式
|
|
1858
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"加速时间"`));
|
|
1859
|
+
expect(targetSnippet.originalCode).toBe(`"加速时间"`);
|
|
1860
|
+
expect(targetSnippet.convertedCode).toBe(`"加速时间"`);
|
|
1861
|
+
expect(targetSnippet.literals).toEqual([
|
|
1862
|
+
'加速时间'
|
|
1863
|
+
]);
|
|
1864
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1865
|
+
}
|
|
1866
|
+
});
|
|
1867
|
+
|
|
1868
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1869
|
+
test('should handle string in comment 5', () => {
|
|
1870
|
+
const code = `
|
|
1871
|
+
m_text_percent.text = $"{curGoodsConfig.RebateRate}%";
|
|
1872
|
+
m_name_holder.url = FUISys.Instance.GetIconUrl(_curShopDetail.ShopConfig.Name);
|
|
1873
|
+
m_thumbnail_holder.url = FUISys.Instance.GetIconUrl(_curShopDetail.ShopConfig.Thumbnail);
|
|
1874
|
+
m_btn_buy.text = $"¥ {curGoodsConfig.Price}";
|
|
1875
|
+
m_text_timeleft.text = curShop.TimeLimitData.RemainTime().TR() + "后消失".TR();
|
|
1876
|
+
`;
|
|
1877
|
+
const snippets = extractor.extractStrings(code);
|
|
1878
|
+
{
|
|
1879
|
+
let targetSnippet = snippets[2];
|
|
1880
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`));
|
|
1881
|
+
expect(targetSnippet.originalCode).toBe(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`);
|
|
1882
|
+
expect(targetSnippet.convertedCode).toBe(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`);
|
|
1883
|
+
expect(targetSnippet.literals).toEqual([
|
|
1884
|
+
'后消失'
|
|
1885
|
+
]);
|
|
1886
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1887
|
+
}
|
|
1888
|
+
});
|
|
1889
|
+
|
|
1890
|
+
// 正确处理C# `switch` 表达式形式中的字符串表达式
|
|
1891
|
+
test('should handle switch expression string', () => {
|
|
1892
|
+
const code = `
|
|
1893
|
+
case (int)State.Lock:
|
|
1894
|
+
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
1895
|
+
break;
|
|
1896
|
+
`;
|
|
1897
|
+
const snippets = extractor.extractStrings(code);
|
|
1898
|
+
{
|
|
1899
|
+
let targetSnippet = snippets[0];
|
|
1900
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`));
|
|
1901
|
+
expect(targetSnippet.originalCode).toBe(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`);
|
|
1902
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("灵田{0}级解锁", _model.GetFarmLandUnlockLevel(_landId))`);
|
|
1903
|
+
expect(targetSnippet.literals).toEqual([
|
|
1904
|
+
'灵田{0}级解锁'
|
|
1905
|
+
]);
|
|
1906
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1907
|
+
}
|
|
1908
|
+
});
|
|
1909
|
+
|
|
1910
|
+
// 正确识别C# 行注释语句边界, 行注释不能影响上下行的字符串提取
|
|
1911
|
+
test('should handle comment boundary 1', () => {
|
|
1912
|
+
const code = `
|
|
1913
|
+
//上锁
|
|
1914
|
+
case (int)State.Lock:
|
|
1915
|
+
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
1916
|
+
break;
|
|
1917
|
+
`;
|
|
1918
|
+
const snippets = extractor.extractStrings(code);
|
|
1919
|
+
{
|
|
1920
|
+
let targetSnippet = snippets[0];
|
|
1921
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`));
|
|
1922
|
+
expect(targetSnippet.originalCode).toBe(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`);
|
|
1923
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("灵田{0}级解锁", _model.GetFarmLandUnlockLevel(_landId))`);
|
|
1924
|
+
expect(targetSnippet.literals).toEqual([
|
|
1925
|
+
'灵田{0}级解锁'
|
|
1926
|
+
]);
|
|
1927
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1928
|
+
}
|
|
1929
|
+
});
|
|
1930
|
+
|
|
1931
|
+
// 正确识别C# 行注释语句边界, 行注释不能影响上下行的字符串提取
|
|
1932
|
+
test('should handle comment boundary 2', () => {
|
|
1933
|
+
const code = `
|
|
1934
|
+
// klwjfe
|
|
1935
|
+
namespace TestNamespace{
|
|
1936
|
+
// lkwjfe
|
|
1937
|
+
public class FK{
|
|
1938
|
+
// klwf
|
|
1939
|
+
public void TestM(){
|
|
1940
|
+
// 模拟状态变量
|
|
1941
|
+
var _state = (int)State.Lock;
|
|
1942
|
+
// 模拟土地ID变量
|
|
1943
|
+
switch (_state){
|
|
1944
|
+
//上锁
|
|
1945
|
+
case (int)State.Lock:
|
|
1946
|
+
// lkwjefl
|
|
1947
|
+
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
1948
|
+
// klwejf
|
|
1949
|
+
break;
|
|
1950
|
+
// lkwjf
|
|
1951
|
+
}
|
|
1952
|
+
// klwjfel
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
`;
|
|
1957
|
+
const snippets = extractor.extractStrings(code);
|
|
1958
|
+
{
|
|
1959
|
+
let targetSnippet = snippets[0];
|
|
1960
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`));
|
|
1961
|
+
expect(targetSnippet.originalCode).toBe(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`);
|
|
1962
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("灵田{0}级解锁", _model.GetFarmLandUnlockLevel(_landId))`);
|
|
1963
|
+
expect(targetSnippet.literals).toEqual([
|
|
1964
|
+
'灵田{0}级解锁'
|
|
1965
|
+
]);
|
|
1966
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1967
|
+
}
|
|
1968
|
+
});
|
|
1969
|
+
// 正确识别C# 行注释语句边界, 行注释不能影响上下行的字符串提取
|
|
1970
|
+
test('should handle comment boundary 2', () => {
|
|
1971
|
+
const code = `
|
|
1972
|
+
// klwjfe
|
|
1973
|
+
namespace TestNamespace{
|
|
1974
|
+
// lkwjfe
|
|
1975
|
+
public class FK{
|
|
1976
|
+
// wlkjelj
|
|
1977
|
+
private int Llkwe = 23;
|
|
1978
|
+
// lkjlkj
|
|
1979
|
+
private int Dwekl { get; set; } = 23;
|
|
1980
|
+
// jklwef
|
|
1981
|
+
private static int Dwekl { get; set; } = 23;
|
|
1982
|
+
// lkwjeflk
|
|
1983
|
+
public static void TestM(){}
|
|
1984
|
+
// wesd
|
|
1985
|
+
public static void TestM()
|
|
1986
|
+
{
|
|
1987
|
+
}
|
|
1988
|
+
// wesd
|
|
1989
|
+
public static void TestM(){
|
|
1990
|
+
}
|
|
1991
|
+
// klwf
|
|
1992
|
+
public void TestM(){
|
|
1993
|
+
// 模拟状态变量
|
|
1994
|
+
var _state = (int)State.Lock;
|
|
1995
|
+
// 模拟土地ID变量
|
|
1996
|
+
switch (_state){
|
|
1997
|
+
//上锁
|
|
1998
|
+
case (int)State.Lock:
|
|
1999
|
+
// lkwjefl
|
|
2000
|
+
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
2001
|
+
// klwejf
|
|
2002
|
+
break;
|
|
2003
|
+
// lkwjf
|
|
2004
|
+
}
|
|
2005
|
+
// klwjfel
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
`;
|
|
2010
|
+
const snippets = extractor.extractStrings(code);
|
|
2011
|
+
{
|
|
2012
|
+
let targetSnippet = snippets[0];
|
|
2013
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`));
|
|
2014
|
+
expect(targetSnippet.originalCode).toBe(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`);
|
|
2015
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("灵田{0}级解锁", _model.GetFarmLandUnlockLevel(_landId))`);
|
|
2016
|
+
expect(targetSnippet.literals).toEqual([
|
|
2017
|
+
'灵田{0}级解锁'
|
|
2018
|
+
]);
|
|
2019
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2020
|
+
}
|
|
2021
|
+
});
|
|
2022
|
+
|
|
2023
|
+
// 正确识别C#文档注释边界, 类、方法、类成员的文档注释需要直接忽略捕获, 不参与字符串表达式提取; 文档注释通常位于类、方法、类成员的定义上方, 文档注释的格式形如: ` /// <xxx> yyy\n /// </xxx>` 或 ` /// <xxx yyy/>`, 其中xxx为标签, yyy为注释内容, `<xxx>`和`</xxx>` 不一定在同一行或不同行, ` /// <xxx> yyy\n` 不一定只有一行; 文档注释通常以`<xxx>`标签开始, 以`</xxx>`标签结束, 或者以 `<xxx ` 开始, 以 `/>` 结束。
|
|
2024
|
+
test('should handle doc comment boundary for class/method/members', () => {
|
|
2025
|
+
const code = `
|
|
2026
|
+
/// <summary>
|
|
2027
|
+
/// "fwef 类注释1"
|
|
2028
|
+
/// $"fwef 类注释2"
|
|
2029
|
+
/// $"fwef 类注释2 {wef}"
|
|
2030
|
+
/// wef $"fwef 类注释2 {wef}" wef
|
|
2031
|
+
/// </summary>
|
|
2032
|
+
/// <sumary "lkwjfelj"/>
|
|
2033
|
+
public partial class TimeLimitedChargeDialog
|
|
2034
|
+
{
|
|
2035
|
+
/// <summary>
|
|
2036
|
+
/// $" Property成员注释 dsvdf {wlpoe}"
|
|
2037
|
+
/// </summary>
|
|
2038
|
+
private int Ljfw { get; set; } = 342;
|
|
2039
|
+
|
|
2040
|
+
/// <summary>
|
|
2041
|
+
/// $" Field成员注释 wfewe {vvwe}"
|
|
2042
|
+
/// $" Field成员注释 wfewe {vvwe}" wfe
|
|
2043
|
+
/// </summary>
|
|
2044
|
+
private int Ljfw = 342;
|
|
2045
|
+
|
|
2046
|
+
/// <summary>
|
|
2047
|
+
///</summary>
|
|
2048
|
+
private int Ljfw = 342;
|
|
2049
|
+
|
|
2050
|
+
/// <summary>
|
|
2051
|
+
/// " wef方法注释 wef"
|
|
2052
|
+
/// $" wef方法注释 wef"
|
|
2053
|
+
/// $" wef方法注释 wef{wef}"
|
|
2054
|
+
/// wfe $" wef方法注释 wef{wef}"
|
|
2055
|
+
/// wfe $" wef方法注释 wef{wef}" wef
|
|
2056
|
+
///wfe $" wef方法注释 wef{wef}" wef
|
|
2057
|
+
/// wefw $" wef方法注释 wef{wef}" we
|
|
2058
|
+
/// </summary>
|
|
2059
|
+
/// <sumary wf $"klwf"/>
|
|
2060
|
+
/// <param name="force">是否重新创建页签列表</param>
|
|
2061
|
+
private void RefreshGoodsInfo()
|
|
2062
|
+
{
|
|
2063
|
+
m_text_timeleft.text = curShop.TimeLimitData.RemainTime() + "后消失";
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
`;
|
|
2067
|
+
const snippets = extractor.extractStrings(code);
|
|
2068
|
+
{
|
|
2069
|
+
let targetSnippet = snippets[0];
|
|
2070
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2071
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`curShop.TimeLimitData.RemainTime() + "后消失"`));
|
|
2072
|
+
expect(targetSnippet.originalCode).toBe(`curShop.TimeLimitData.RemainTime() + "后消失"`);
|
|
2073
|
+
expect(targetSnippet.convertedCode).toBe(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`);
|
|
2074
|
+
expect(targetSnippet.literals).toEqual([
|
|
2075
|
+
'后消失'
|
|
2076
|
+
]);
|
|
2077
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2078
|
+
}
|
|
2079
|
+
});
|
|
2080
|
+
|
|
2081
|
+
// 正确识别C#方法参数中的字符串表达式, 支持1到多个形参有默认值的情形
|
|
2082
|
+
test('should handle string expression in method call parameter 1', () => {
|
|
2083
|
+
const code = `
|
|
2084
|
+
namespace FaBao.UI.Comp
|
|
2085
|
+
{
|
|
2086
|
+
public partial class ItemCommonComp
|
|
2087
|
+
{
|
|
2088
|
+
public void BindData(bool needCompare = false)
|
|
2089
|
+
{
|
|
2090
|
+
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
`;
|
|
2095
|
+
const snippets = extractor.extractStrings(code);
|
|
2096
|
+
{
|
|
2097
|
+
let targetSnippet = snippets[0];
|
|
2098
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2099
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}阶", _itemConfig.PillLevel)`));
|
|
2100
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2101
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2102
|
+
expect(targetSnippet.literals).toEqual([
|
|
2103
|
+
'{0}阶'
|
|
2104
|
+
]);
|
|
2105
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2106
|
+
}
|
|
2107
|
+
expect(snippets.length).toBe(1);
|
|
2108
|
+
});
|
|
2109
|
+
|
|
2110
|
+
// 正确识别C#方法参数中的字符串表达式, 支持1到多个形参有默认值的情形
|
|
2111
|
+
test('should handle string expression in method call parameter 2', () => {
|
|
2112
|
+
const code = `
|
|
2113
|
+
namespace FaBao.UI.Comp
|
|
2114
|
+
{
|
|
2115
|
+
public partial class ItemCommonComp
|
|
2116
|
+
{
|
|
2117
|
+
public void BindData(bool needCompare = false, long needCompare2 = 23, float needCompare2 = 324.0)
|
|
2118
|
+
{
|
|
2119
|
+
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
`;
|
|
2124
|
+
const snippets = extractor.extractStrings(code);
|
|
2125
|
+
{
|
|
2126
|
+
let targetSnippet = snippets[0];
|
|
2127
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2128
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}阶", _itemConfig.PillLevel)`));
|
|
2129
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2130
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2131
|
+
expect(targetSnippet.literals).toEqual([
|
|
2132
|
+
'{0}阶'
|
|
2133
|
+
]);
|
|
2134
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2135
|
+
}
|
|
2136
|
+
expect(snippets.length).toBe(1);
|
|
2137
|
+
});
|
|
2138
|
+
|
|
2139
|
+
// 正确识别C#方法参数中的字符串表达式, 支持1到多个形参有默认值的情形
|
|
2140
|
+
test('should handle string expression in method call parameter 3', () => {
|
|
2141
|
+
const code = `
|
|
2142
|
+
namespace FaBao.UI.Comp
|
|
2143
|
+
{
|
|
2144
|
+
public partial class ItemCommonComp
|
|
2145
|
+
{
|
|
2146
|
+
public void BindData(string wkle, bool needCompare = false, int needCompare2 = false)
|
|
2147
|
+
{
|
|
2148
|
+
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
`;
|
|
2153
|
+
const snippets = extractor.extractStrings(code);
|
|
2154
|
+
{
|
|
2155
|
+
let targetSnippet = snippets[0];
|
|
2156
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2157
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}阶", _itemConfig.PillLevel)`));
|
|
2158
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2159
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2160
|
+
expect(targetSnippet.literals).toEqual([
|
|
2161
|
+
'{0}阶'
|
|
2162
|
+
]);
|
|
2163
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2164
|
+
}
|
|
2165
|
+
expect(snippets.length).toBe(1);
|
|
2166
|
+
});
|
|
2167
|
+
|
|
2168
|
+
// 正确提取C#方法参数中的字符串表达式信息, 支持1到多个形参有默认值的情形
|
|
2169
|
+
test('should handle string expression in method call parameter 3', () => {
|
|
2170
|
+
const code = `
|
|
2171
|
+
namespace FaBao.UI.Comp
|
|
2172
|
+
{
|
|
2173
|
+
public partial class ItemCommonComp
|
|
2174
|
+
{
|
|
2175
|
+
public void BindData(string wkle = "11111", bool needCompare = false, int needCompare2 = false)
|
|
2176
|
+
{
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
public void BindData(string wkle = "22", string wkle = "werwer", bool needCompare = false, string wkle = "wefwewef31f", int needCompare2 = false, string wkle = "df223")
|
|
2180
|
+
{
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
public void BindData(string wkle = "(*&%\\\\*(@Fwfe))&(")
|
|
2184
|
+
{
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
public void BindData(string we, string wkle = "aaaaa", bool needCompare = false, int needCompare2 = false)
|
|
2188
|
+
{
|
|
2189
|
+
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
`;
|
|
2194
|
+
const snippets = extractor.extractStrings(code);
|
|
2195
|
+
{
|
|
2196
|
+
let targetSnippet = snippets[0];
|
|
2197
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2198
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"11111"`));
|
|
2199
|
+
expect(targetSnippet.originalCode).toBe(`"11111"`);
|
|
2200
|
+
expect(targetSnippet.convertedCode).toBe(`"11111"`);
|
|
2201
|
+
expect(targetSnippet.literals).toEqual([
|
|
2202
|
+
'11111'
|
|
2203
|
+
]);
|
|
2204
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2205
|
+
}
|
|
2206
|
+
{
|
|
2207
|
+
let targetSnippet = snippets[1];
|
|
2208
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2209
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"22"`));
|
|
2210
|
+
expect(targetSnippet.originalCode).toBe(`"22"`);
|
|
2211
|
+
expect(targetSnippet.convertedCode).toBe(`"22"`);
|
|
2212
|
+
expect(targetSnippet.literals).toEqual([
|
|
2213
|
+
'22'
|
|
2214
|
+
]);
|
|
2215
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2216
|
+
}
|
|
2217
|
+
{
|
|
2218
|
+
let targetSnippet = snippets[2];
|
|
2219
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2220
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"werwer"`));
|
|
2221
|
+
expect(targetSnippet.originalCode).toBe(`"werwer"`);
|
|
2222
|
+
expect(targetSnippet.convertedCode).toBe(`"werwer"`);
|
|
2223
|
+
expect(targetSnippet.literals).toEqual([
|
|
2224
|
+
'werwer'
|
|
2225
|
+
]);
|
|
2226
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2227
|
+
}
|
|
2228
|
+
{
|
|
2229
|
+
let targetSnippet = snippets[3];
|
|
2230
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2231
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"wefwewef31f"`));
|
|
2232
|
+
expect(targetSnippet.originalCode).toBe(`"wefwewef31f"`);
|
|
2233
|
+
expect(targetSnippet.convertedCode).toBe(`"wefwewef31f"`);
|
|
2234
|
+
expect(targetSnippet.literals).toEqual([
|
|
2235
|
+
'wefwewef31f'
|
|
2236
|
+
]);
|
|
2237
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2238
|
+
}
|
|
2239
|
+
{
|
|
2240
|
+
let targetSnippet = snippets[4];
|
|
2241
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2242
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"df223"`));
|
|
2243
|
+
expect(targetSnippet.originalCode).toBe(`"df223"`);
|
|
2244
|
+
expect(targetSnippet.convertedCode).toBe(`"df223"`);
|
|
2245
|
+
expect(targetSnippet.literals).toEqual([
|
|
2246
|
+
'df223'
|
|
2247
|
+
]);
|
|
2248
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2249
|
+
}
|
|
2250
|
+
{
|
|
2251
|
+
let targetSnippet = snippets[5];
|
|
2252
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2253
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"(*&%\\\\*(@Fwfe))&("`));
|
|
2254
|
+
expect(targetSnippet.originalCode).toBe(`"(*&%\\\\*(@Fwfe))&("`);
|
|
2255
|
+
expect(targetSnippet.convertedCode).toBe(`"(*&%\\\\*(@Fwfe))&("`);
|
|
2256
|
+
expect(targetSnippet.literals).toEqual([
|
|
2257
|
+
'(*&%\\\\*(@Fwfe))&('
|
|
2258
|
+
]);
|
|
2259
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2260
|
+
}
|
|
2261
|
+
{
|
|
2262
|
+
let targetSnippet = snippets[6];
|
|
2263
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2264
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"aaaaa"`));
|
|
2265
|
+
expect(targetSnippet.originalCode).toBe(`"aaaaa"`);
|
|
2266
|
+
expect(targetSnippet.convertedCode).toBe(`"aaaaa"`);
|
|
2267
|
+
expect(targetSnippet.literals).toEqual([
|
|
2268
|
+
'aaaaa'
|
|
2269
|
+
]);
|
|
2270
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2271
|
+
}
|
|
2272
|
+
{
|
|
2273
|
+
let targetSnippet = snippets[7];
|
|
2274
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2275
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}阶", _itemConfig.PillLevel)`));
|
|
2276
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2277
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2278
|
+
expect(targetSnippet.literals).toEqual([
|
|
2279
|
+
'{0}阶'
|
|
2280
|
+
]);
|
|
2281
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2282
|
+
}
|
|
2283
|
+
});
|
|
2284
|
+
|
|
2285
|
+
// 需要正确识别C#代码中 `if` 语句边界 和 创建对象表达式的边界, 识别 `if` 语句前、中、后部分中的字符串表达式
|
|
2286
|
+
test('should handle if border and object creation expression border', () => {
|
|
2287
|
+
const code = `
|
|
2288
|
+
namespace FaBao.UI.MainUI
|
|
2289
|
+
{
|
|
2290
|
+
public partial class SpellUpgradeDialog
|
|
2291
|
+
{
|
|
2292
|
+
private async void OnBtnUpgrade()
|
|
2293
|
+
{
|
|
2294
|
+
// new SpellCard_Action_UpgradeSpellCard(_symbolCard.Id) 被方法调用传参的 () 包裹, 因此已经构成了完整的对象创建表达式
|
|
2295
|
+
if (await this.GetModel<SpellCardModel>().DispatchAction(new SpellCard_Action_UpgradeSpellCard(_symbolCard.Id)))
|
|
2296
|
+
{
|
|
2297
|
+
//升级成功后刷新界面
|
|
2298
|
+
m_text_level.text = Tr.Format("{0}级", _symbolCard.Level);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
`;
|
|
2304
|
+
const snippets = extractor.extractStrings(code);
|
|
2305
|
+
{
|
|
2306
|
+
let targetSnippet = snippets[0];
|
|
2307
|
+
// 需要正确识别 `if` 语句边界, 识别 `if` 语句前、中、后部分中的字符串表达式
|
|
2308
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}级", _symbolCard.Level)`));
|
|
2309
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}级", _symbolCard.Level)`);
|
|
2310
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}级", _symbolCard.Level)`);
|
|
2311
|
+
expect(targetSnippet.literals).toEqual([
|
|
2312
|
+
'{0}级'
|
|
2313
|
+
]);
|
|
2314
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2315
|
+
}
|
|
2316
|
+
expect(snippets.length).toBe(1);
|
|
2317
|
+
});
|
|
2318
|
+
|
|
2319
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2320
|
+
test('should handle class member initialization assignment with anonymous function 1', () => {
|
|
2321
|
+
const code = `
|
|
2322
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2323
|
+
{
|
|
2324
|
+
Title = "提示",
|
|
2325
|
+
ConfirmCallback = async () =>
|
|
2326
|
+
{
|
|
2327
|
+
//灵纹一键下阵
|
|
2328
|
+
if (await this.GetModel<CardModel>().DispatchAction(new Rune_Action_CleanRune(_sutraCardData.Card.Id)))
|
|
2329
|
+
{
|
|
2330
|
+
Toast.Info("卸载成功");
|
|
2331
|
+
}
|
|
2332
|
+
},
|
|
2333
|
+
CancelText = "取消",
|
|
2334
|
+
}).Forget();
|
|
2335
|
+
`;
|
|
2336
|
+
const snippets = extractor.extractStrings(code);
|
|
2337
|
+
{
|
|
2338
|
+
let targetSnippet = snippets[0];
|
|
2339
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"提示"`));
|
|
2340
|
+
expect(targetSnippet.originalCode).toBe(`"提示"`);
|
|
2341
|
+
expect(targetSnippet.convertedCode).toBe(`"提示"`);
|
|
2342
|
+
expect(targetSnippet.literals).toEqual([
|
|
2343
|
+
'提示'
|
|
2344
|
+
]);
|
|
2345
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2346
|
+
}
|
|
2347
|
+
{
|
|
2348
|
+
let targetSnippet = snippets[1];
|
|
2349
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2350
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"卸载成功"`));
|
|
2351
|
+
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
2352
|
+
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
2353
|
+
expect(targetSnippet.literals).toEqual([
|
|
2354
|
+
'卸载成功'
|
|
2355
|
+
]);
|
|
2356
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2357
|
+
}
|
|
2358
|
+
{
|
|
2359
|
+
let targetSnippet = snippets[2];
|
|
2360
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"取消"`));
|
|
2361
|
+
expect(targetSnippet.originalCode).toBe(`"取消"`);
|
|
2362
|
+
expect(targetSnippet.convertedCode).toBe(`"取消"`);
|
|
2363
|
+
expect(targetSnippet.literals).toEqual([
|
|
2364
|
+
'取消'
|
|
2365
|
+
]);
|
|
2366
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2367
|
+
}
|
|
2368
|
+
});
|
|
2369
|
+
|
|
2370
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2371
|
+
test('should handle class member initialization assignment with anonymous function 2', () => {
|
|
2372
|
+
const code = `
|
|
2373
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2374
|
+
{
|
|
2375
|
+
ConfirmCallback = async () =>
|
|
2376
|
+
{
|
|
2377
|
+
Toast.Info("卸载成功");
|
|
2378
|
+
},
|
|
2379
|
+
}).Forget();
|
|
2380
|
+
`;
|
|
2381
|
+
const snippets = extractor.extractStrings(code);
|
|
2382
|
+
{
|
|
2383
|
+
let targetSnippet = snippets[0];
|
|
2384
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2385
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"卸载成功"`));
|
|
2386
|
+
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
2387
|
+
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
2388
|
+
expect(targetSnippet.literals).toEqual([
|
|
2389
|
+
'卸载成功'
|
|
2390
|
+
]);
|
|
2391
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2392
|
+
}
|
|
2393
|
+
});
|
|
2394
|
+
|
|
2395
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2396
|
+
test('should handle class member initialization assignment with anonymous function 2', () => {
|
|
2397
|
+
const code = `
|
|
2398
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2399
|
+
{
|
|
2400
|
+
ConfirmCallback = (int qwfewe) =>
|
|
2401
|
+
{
|
|
2402
|
+
Toast.Info($"卸载成功: {qwfewe}");
|
|
2403
|
+
},
|
|
2404
|
+
}).Forget();
|
|
2405
|
+
`;
|
|
2406
|
+
const snippets = extractor.extractStrings(code);
|
|
2407
|
+
{
|
|
2408
|
+
let targetSnippet = snippets[0];
|
|
2409
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2410
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"卸载成功: {qwfewe}"`));
|
|
2411
|
+
expect(targetSnippet.originalCode).toBe(`$"卸载成功: {qwfewe}"`);
|
|
2412
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("卸载成功: {0}", qwfewe)`);
|
|
2413
|
+
expect(targetSnippet.literals).toEqual([
|
|
2414
|
+
'卸载成功: {0}'
|
|
2415
|
+
]);
|
|
2416
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2417
|
+
}
|
|
2418
|
+
});
|
|
2419
|
+
|
|
2420
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2421
|
+
test('should handle class member initialization assignment with anonymous function 3', () => {
|
|
2422
|
+
const code = `
|
|
2423
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2424
|
+
{
|
|
2425
|
+
ConfirmCallback = async () => Toast.Info("卸载成功"),
|
|
2426
|
+
}).Forget();
|
|
2427
|
+
`;
|
|
2428
|
+
const snippets = extractor.extractStrings(code);
|
|
2429
|
+
{
|
|
2430
|
+
let targetSnippet = snippets[0];
|
|
2431
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2432
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"卸载成功"`));
|
|
2433
|
+
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
2434
|
+
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
2435
|
+
expect(targetSnippet.literals).toEqual([
|
|
2436
|
+
'卸载成功'
|
|
2437
|
+
]);
|
|
2438
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2439
|
+
}
|
|
2440
|
+
});
|
|
2441
|
+
|
|
2442
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2443
|
+
test('should handle class member initialization assignment with anonymous function 4', () => {
|
|
2444
|
+
const code = `
|
|
2445
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2446
|
+
{
|
|
2447
|
+
ConfirmCallback = () => Toast.Info("卸载成功"),
|
|
2448
|
+
}).Forget();
|
|
2449
|
+
`;
|
|
2450
|
+
const snippets = extractor.extractStrings(code);
|
|
2451
|
+
{
|
|
2452
|
+
let targetSnippet = snippets[0];
|
|
2453
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2454
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"卸载成功"`));
|
|
2455
|
+
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
2456
|
+
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
2457
|
+
expect(targetSnippet.literals).toEqual([
|
|
2458
|
+
'卸载成功'
|
|
2459
|
+
]);
|
|
2460
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2461
|
+
}
|
|
2462
|
+
});
|
|
2463
|
+
|
|
2464
|
+
// 测试处理 `xxx.text = yyy` 形式赋值语句, 以 `.text =` 给 `text` 成员赋值的表达式中, `yyy` 部分必定是字符串表达式; 如果`yyy`中不存在字符串, 则`yyy` 中以 `+` 连接的表达式需要加上 `.TR()`; 如果 `yyy` 是作为值表达式整体(必定返回字符串类型值), 也需要追加 `.TR()`。
|
|
2465
|
+
test('should handle .text = format 1', () => {
|
|
2466
|
+
const code = `m_text_iwff.text = info ;`;
|
|
2467
|
+
const snippets = extractor.extractStrings(code);
|
|
2468
|
+
{
|
|
2469
|
+
let targetSnippet = snippets[0];
|
|
2470
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`info`));
|
|
2471
|
+
expect(targetSnippet.originalCode).toBe(`info`);
|
|
2472
|
+
expect(targetSnippet.convertedCode).toBe(`info.TR()`);
|
|
2473
|
+
expect(targetSnippet.literals).toEqual([
|
|
2474
|
+
]);
|
|
2475
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2476
|
+
}
|
|
2477
|
+
});
|
|
2478
|
+
|
|
2479
|
+
// 测试处理 `xxx.text = yyy` 形式赋值语句, 以 `.text =` 给 `text` 成员赋值的表达式中, `yyy` 部分必定是字符串表达式; 如果`yyy`中不存在字符串, 则`yyy` 中以 `+` 连接的表达式需要加上 `.TR()`; 如果 `yyy` 是作为值表达式整体(必定返回字符串类型值), 也需要追加 `.TR()`。
|
|
2480
|
+
test('should handle .text = format 1', () => {
|
|
2481
|
+
const code = `m_text_info.text = info1.member1 + info2.member2;`;
|
|
2482
|
+
const snippets = extractor.extractStrings(code);
|
|
2483
|
+
{
|
|
2484
|
+
let targetSnippet = snippets[0];
|
|
2485
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`info1.member1 + info2.member2`));
|
|
2486
|
+
expect(targetSnippet.originalCode).toBe(`info1.member1 + info2.member2`);
|
|
2487
|
+
expect(targetSnippet.convertedCode).toBe(`info1.member1.TR() + info2.member2.TR()`);
|
|
2488
|
+
expect(targetSnippet.literals).toEqual([
|
|
2489
|
+
]);
|
|
2490
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2491
|
+
}
|
|
2492
|
+
});
|
|
2493
|
+
|
|
1029
2494
|
});
|