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