scancscode 1.0.57 → 1.0.58
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-if-else-single-statement-value-extraction/checklist.md +7 -0
- package/.trae/specs/fix-if-else-single-statement-value-extraction/spec.md +41 -0
- package/.trae/specs/fix-if-else-single-statement-value-extraction/tasks.md +14 -0
- package/dist/src/CSVUtils.js +7 -5
- package/dist/src/CmdExecutor.js +1 -1
- package/dist/src/CsvAutoTranslator.js +5 -114
- package/dist/src/LanguageMap.js +113 -0
- package/dist/test/CSharpStringExtractor.test.js +2629 -2376
- package/dist/test/CsvAutoTranslator.test.js +166 -165
- package/dist/test/TestConvert.test.js +3 -1
- package/package.json +1 -1
- package/src/CSVUtils.ts +7 -5
- package/src/CmdExecutor.ts +1 -1
- package/src/CsvAutoTranslator.ts +6 -162
- package/src/LanguageMap.ts +158 -0
- package/test/Auto.csv +12544 -3
- package/test/Auto1.csv +4 -0
- package/test/CSharpStringExtractor.test.ts +2020 -1650
- package/test/CsvAutoTranslator.test.ts +196 -192
- package/test/TestConvert.test.ts +2 -1
|
@@ -9,563 +9,427 @@ describe('CSharpStringExtractor', () => {
|
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
// 测试从普通函数调用参数中提取字符串表达式信息, 只需要提取参数中的字符串值表达式, 不需要对提取的字符串表达式进行处理
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
test('should handle .text = format 1', () => {
|
|
15
|
-
const code = `m_text_iwff.text = info ;`;
|
|
12
|
+
test('should extract plain strings', () => {
|
|
13
|
+
const code = 'Console.WriteLine("Hello, world!");';
|
|
16
14
|
const snippets = extractor.extractStrings(code);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
})
|
|
27
|
-
test('should handle .text = format 2', () => {
|
|
28
|
-
const code = `m_text_info.text = info1.member1 + info2.member2;`;
|
|
15
|
+
|
|
16
|
+
expect(snippets.length).toBe(1);
|
|
17
|
+
expect(snippets[0].literals).toEqual(['Hello, world!']);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// 已经追加 `.TR()` 后缀的字符串表达式不需要重复追加 `.TR()`
|
|
21
|
+
test('should handle strings with .TR() already appended', () => {
|
|
22
|
+
const code = 'obj.prop = "Hello, world!".TR();';
|
|
29
23
|
const snippets = extractor.extractStrings(code);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
expect(targetSnippet.literals).toEqual([
|
|
36
|
-
]);
|
|
37
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
38
|
-
}
|
|
39
|
-
})
|
|
24
|
+
|
|
25
|
+
expect(snippets.length).toBe(1);
|
|
26
|
+
expect(snippets[0].originalCode).toBe('"Hello, world!".TR()');
|
|
27
|
+
expect(snippets[0].convertedCode).toBe('"Hello, world!".TR()');
|
|
28
|
+
expect(snippets[0].isChanged).toBe(false);
|
|
40
29
|
});
|
|
41
30
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const code = '
|
|
31
|
+
// 测试从普通函数调用参数中提取字符串表达式信息, 只需要提取参数中的字符串值表达式, 不需要对提取的字符串表达式进行处理, 也不需要追加 `.TR()`
|
|
32
|
+
test('should not add .TR() to function arguments', () => {
|
|
33
|
+
const code = 'CallFunc("Hello, world!");';
|
|
45
34
|
const snippets = extractor.extractStrings(code);
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
expect(
|
|
49
|
-
expect(
|
|
50
|
-
expect(snippet.literals).toEqual(['[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]']);
|
|
51
|
-
expect(snippet.isChanged).toBe(true);
|
|
52
|
-
})
|
|
36
|
+
expect(snippets.length).toBe(1);
|
|
37
|
+
expect(snippets[0].originalCode).toBe('"Hello, world!"');
|
|
38
|
+
expect(snippets[0].convertedCode).toBe('"Hello, world!"');
|
|
53
39
|
});
|
|
54
40
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const code =
|
|
41
|
+
// 测试从普通属性赋值语句中提取字符串表达式信息, 只需要提取赋值表达式中的字符串值表达式, 不需要对提取的字符串表达式进行处理, 也不需要追加 `.TR()`
|
|
42
|
+
test('should not add .TR() to regular property assignments', () => {
|
|
43
|
+
const code = 'obj.prop = "Hello, world!";';
|
|
58
44
|
const snippets = extractor.extractStrings(code);
|
|
59
45
|
|
|
60
|
-
|
|
61
|
-
expect(snippets.
|
|
46
|
+
expect(snippets.length).toBe(1);
|
|
47
|
+
expect(snippets[0].originalCode).toBe('"Hello, world!"');
|
|
48
|
+
expect(snippets[0].convertedCode).toBe('"Hello, world!"');
|
|
49
|
+
});
|
|
62
50
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
expect(targetSnippet.literals).toEqual([
|
|
67
|
-
'下一轮神兽出现倒计时: {0}'
|
|
68
|
-
]);
|
|
69
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
70
|
-
})
|
|
71
|
-
test('should handle bracket 2', () => {
|
|
72
|
-
const code = `m_text_time.text = $"神兽离去时间: {Date.FeGetInterpolatedTime(ServerTimer.Instance.Time, _endGameStamp)}";`
|
|
51
|
+
// 测试从 $"" 字符串模板(也叫内插字符串)中提取字符串表达式信息, 需要先将字符串模板转换为 `string.Format(...)` 格式, 然后将 `string.Format(...)` 替换为 `Tr.Format(...)`, 之后从 `Tr.Format(...)` 的函数调用参数中提取普通字符串、或进一步递归提取字符串表达式信息
|
|
52
|
+
test('should handle $"" string templates', () => {
|
|
53
|
+
const code = 'var label1 = $"Hello, {name}!";';
|
|
73
54
|
const snippets = extractor.extractStrings(code);
|
|
74
55
|
|
|
75
|
-
|
|
76
|
-
expect(snippets.
|
|
56
|
+
expect(snippets.length).toBe(1);
|
|
57
|
+
expect(snippets[0].originalCode).toBe('$"Hello, {name}!"');
|
|
58
|
+
expect(snippets[0].literals).toContain('Hello, {0}!');
|
|
59
|
+
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
60
|
+
});
|
|
77
61
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
expect(targetSnippet.literals).toEqual([
|
|
82
|
-
'神兽离去时间: {0}'
|
|
83
|
-
]);
|
|
84
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
85
|
-
})
|
|
86
|
-
test('should handle bracket 3', () => {
|
|
87
|
-
const code = `desc += $"剩余{ToGetInterpolatedTime(_cardPoolData.FinishTime * 1000, ServerTimer.Instance.Time)}";`
|
|
62
|
+
// 测试从普通函数调用参数中提取 $"" 字符串模板(也叫内插字符串), 需要先将字符串模板转换为 `string.Format(...)` 格式, 然后将 `string.Format(...)` 替换为 `Tr.Format(...)`, 之后从 `Tr.Format(...)` 的函数调用参数中提取普通字符串、或进一步递归提取字符串表达式信息
|
|
63
|
+
test('should handle $"" string templates in function calls', () => {
|
|
64
|
+
const code = 'CallFunc($"Hello, world: {obj.Func1()}");';
|
|
88
65
|
const snippets = extractor.extractStrings(code);
|
|
89
66
|
|
|
90
|
-
|
|
91
|
-
expect(snippets.
|
|
67
|
+
expect(snippets.length).toBe(1);
|
|
68
|
+
expect(snippets[0].originalCode).toBe('$"Hello, world: {obj.Func1()}"');
|
|
69
|
+
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, world: {0}", obj.Func1())');
|
|
70
|
+
});
|
|
92
71
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
expect(targetSnippet.literals).toEqual([
|
|
97
|
-
'剩余{0}'
|
|
98
|
-
]);
|
|
99
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
100
|
-
})
|
|
101
|
-
test('should handle bracket 4', () => {
|
|
102
|
-
const code = `desc += $"剩余{ToGetInterpolatedTime(FF(_cardPoolData.FinishTime() * 1000, ServerTimer.Instance.Time()))}";`
|
|
72
|
+
// 测试遇到 `string.Format(...)` 形式的字符串表达式, 需要先将 `string.Format(...)` 替换为 `Tr.Format(...)`, 之后从 `Tr.Format(...)` 的函数调用参数中提取普通字符串、或进一步递归提取字符串表达式信息, 内插字符串概念参考: `https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/tokens/interpolated`
|
|
73
|
+
test('should convert string.Format to Tr.Format', () => {
|
|
74
|
+
const code = 'string.Format("Hello, ", name, "!");';
|
|
103
75
|
const snippets = extractor.extractStrings(code);
|
|
104
76
|
|
|
105
|
-
|
|
106
|
-
|
|
77
|
+
expect(snippets.length).toBe(1);
|
|
78
|
+
// string.Format(...) 形式的字符串表达式, 不需要对提取的字符串表达式进行处理, 也不需要追加 `.TR()`
|
|
79
|
+
// string.Format(...) 形式包含的字符串表达式, 需要特殊处理, 连带 `string.Format()` 一起捕获存入 originalCode 成员
|
|
80
|
+
expect(snippets[0].originalCode).toBe('string.Format("Hello, ", name, "!")');
|
|
81
|
+
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, ", name, "!")');
|
|
82
|
+
});
|
|
107
83
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
expect(
|
|
115
|
-
|
|
84
|
+
// 测试遇到 `string.Format(...)` 形式的字符串表达式, 需要先将 `string.Format(...)` 替换为 `Tr.Format(...)`, 之后从 `Tr.Format(...)` 的函数调用参数中提取普通字符串、或进一步递归提取字符串表达式信息
|
|
85
|
+
// 同时测试用 `+` 连接的字符串表达式, 确保用 `+` 符号拼接的字符串表达式被整体处理, 从中提取字符串表达式信息, 而不是分别处理 `+` 两边每个字符串表达式
|
|
86
|
+
test('should handle string.Format in .text assignments', () => {
|
|
87
|
+
const code = 'label.text = Tr.Format("pre", Func(), "sub") + other;';
|
|
88
|
+
const snippets = extractor.extractStrings(code);
|
|
89
|
+
|
|
90
|
+
expect(snippets.length).toBe(1);
|
|
91
|
+
expect(snippets[0].originalCode).toBe('Tr.Format("pre", Func(), "sub") + other');
|
|
92
|
+
expect(snippets[0].literals).toContain('pre');
|
|
93
|
+
expect(snippets[0].literals).toContain('sub');
|
|
116
94
|
});
|
|
117
95
|
|
|
118
|
-
|
|
119
|
-
|
|
96
|
+
// 形如 `m_btn_xxx.title = yyy;` 的赋值语句要和形如 `xxx.text = yyy;` 的赋值语句完全等同处理, 其中 `xxx`和`yyy` 代表某段C#字面量, 可以是对象、字符串、或其他表达式, `m_btn_` 为引用符号名固定前缀; 为了便于理解, 用正则表达式表示, 也就是相当于需要同时匹配 `/^m_btn_\w+\.title\s*=/` 形式的表达式和 `/\w+\.text\s*=/` 形式的表达式, 而其中对于 `xxx` 和 `yyy` 部分的处理逻辑是完全一致的
|
|
97
|
+
test('should handle m_btn_xxx.title = yyy', () => {
|
|
120
98
|
const code = `
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (await this.GetModel<CardModel>().DispatchAction(new Rune_Action_CleanRune(_sutraCardData.Card.Id)))
|
|
128
|
-
{
|
|
129
|
-
Toast.Info("卸载成功");
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
CancelText = "取消",
|
|
133
|
-
}).Forget();
|
|
99
|
+
buy.title = "lkwjelkfj1";
|
|
100
|
+
m_btn1_buy.title = "lkwjelkfj2";
|
|
101
|
+
am_btn_buy.title = "lkwjelkfj3";
|
|
102
|
+
m_btn_buy.title = "lkwjelkfj4";
|
|
103
|
+
m_btn_wwefHwref.title = $"Hello";
|
|
104
|
+
m_btn_fxx_wf.title = $"Hello, {name}!";
|
|
134
105
|
`;
|
|
135
106
|
const snippets = extractor.extractStrings(code);
|
|
136
107
|
{
|
|
137
|
-
let
|
|
138
|
-
expect(
|
|
139
|
-
expect(
|
|
140
|
-
|
|
141
|
-
expect(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
108
|
+
let snippet = snippets[0];
|
|
109
|
+
expect(snippet.originalIndex).toBe(code.indexOf('"lkwjelkfj1"'));
|
|
110
|
+
expect(snippet.originalCode).toBe('"lkwjelkfj1"');
|
|
111
|
+
// `buy` 不符合 `m_btn_` 开头的条件, 不需要强制加 `.TR()`
|
|
112
|
+
expect(snippet.convertedCode).toBe('"lkwjelkfj1"');
|
|
113
|
+
expect(snippet.literals).toContain('lkwjelkfj1');
|
|
114
|
+
expect(snippet.isChanged).toBe(false);
|
|
145
115
|
}
|
|
146
116
|
{
|
|
147
|
-
let
|
|
148
|
-
|
|
149
|
-
expect(
|
|
150
|
-
|
|
151
|
-
expect(
|
|
152
|
-
expect(
|
|
153
|
-
|
|
154
|
-
]);
|
|
155
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
117
|
+
let snippet = snippets[1];
|
|
118
|
+
expect(snippet.originalIndex).toBe(code.indexOf('"lkwjelkfj2"'));
|
|
119
|
+
expect(snippet.originalCode).toBe('"lkwjelkfj2"');
|
|
120
|
+
// `m_btn1_buy` 不符合 `m_btn_` 开头的条件, 不需要强制加 `.TR()`
|
|
121
|
+
expect(snippet.convertedCode).toBe('"lkwjelkfj2"');
|
|
122
|
+
expect(snippet.literals).toContain('lkwjelkfj2');
|
|
123
|
+
expect(snippet.isChanged).toBe(false);
|
|
156
124
|
}
|
|
157
125
|
{
|
|
158
|
-
let
|
|
159
|
-
expect(
|
|
160
|
-
expect(
|
|
161
|
-
|
|
162
|
-
expect(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
126
|
+
let snippet = snippets[2];
|
|
127
|
+
expect(snippet.originalIndex).toBe(code.indexOf('"lkwjelkfj3"'));
|
|
128
|
+
expect(snippet.originalCode).toBe('"lkwjelkfj3"');
|
|
129
|
+
// `am_btn_buy` 不符合 `m_btn_` 开头的条件, 不需要强制加 `.TR()`
|
|
130
|
+
expect(snippet.convertedCode).toBe('"lkwjelkfj3"');
|
|
131
|
+
expect(snippet.literals).toContain('lkwjelkfj3');
|
|
132
|
+
expect(snippet.isChanged).toBe(false);
|
|
166
133
|
}
|
|
167
|
-
})
|
|
168
|
-
test('should handle class member initialization assignment with anonymous function 2', () => {
|
|
169
|
-
const code = `
|
|
170
|
-
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
171
|
-
{
|
|
172
|
-
ConfirmCallback = async () =>
|
|
173
|
-
{
|
|
174
|
-
Toast.Info("卸载成功");
|
|
175
|
-
},
|
|
176
|
-
}).Forget();
|
|
177
|
-
`;
|
|
178
|
-
const snippets = extractor.extractStrings(code);
|
|
179
134
|
{
|
|
180
|
-
let
|
|
181
|
-
|
|
182
|
-
expect(
|
|
183
|
-
|
|
184
|
-
expect(
|
|
185
|
-
expect(
|
|
186
|
-
|
|
187
|
-
]);
|
|
188
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
135
|
+
let snippet = snippets[3];
|
|
136
|
+
expect(snippet.originalIndex).toBe(code.indexOf('"lkwjelkfj4"'));
|
|
137
|
+
expect(snippet.originalCode).toBe('"lkwjelkfj4"');
|
|
138
|
+
// `m_btn_buy` 符合 `m_btn_` 开头的条件, 需要强制加 `.TR()`
|
|
139
|
+
expect(snippet.convertedCode).toBe('"lkwjelkfj4".TR()');
|
|
140
|
+
expect(snippet.literals).toContain('lkwjelkfj4');
|
|
141
|
+
expect(snippet.isChanged).toBe(true);
|
|
189
142
|
}
|
|
190
|
-
})
|
|
191
|
-
test('should handle class member initialization assignment with anonymous function 3', () => {
|
|
192
|
-
const code = `
|
|
193
|
-
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
194
|
-
{
|
|
195
|
-
ConfirmCallback = (int qwfewe) =>
|
|
196
|
-
{
|
|
197
|
-
Toast.Info($"卸载成功: {qwfewe}");
|
|
198
|
-
},
|
|
199
|
-
}).Forget();
|
|
200
|
-
`;
|
|
201
|
-
const snippets = extractor.extractStrings(code);
|
|
202
143
|
{
|
|
203
|
-
let
|
|
204
|
-
|
|
205
|
-
expect(
|
|
206
|
-
|
|
207
|
-
expect(
|
|
208
|
-
expect(
|
|
209
|
-
|
|
210
|
-
]);
|
|
211
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
144
|
+
let snippet = snippets[4];
|
|
145
|
+
expect(snippet.originalIndex).toBe(code.indexOf('$"Hello"'));
|
|
146
|
+
expect(snippet.originalCode).toBe('$"Hello"');
|
|
147
|
+
// `m_btn_wwefHwref` 符合 `m_btn_` 开头的条件, 需要强制加 `.TR()`
|
|
148
|
+
expect(snippet.convertedCode).toBe('$"Hello".TR()');
|
|
149
|
+
expect(snippet.literals).toContain('Hello');
|
|
150
|
+
expect(snippet.isChanged).toBe(true);
|
|
212
151
|
}
|
|
213
|
-
})
|
|
214
|
-
test('should handle class member initialization assignment with anonymous function 4', () => {
|
|
215
|
-
const code = `
|
|
216
|
-
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
217
|
-
{
|
|
218
|
-
ConfirmCallback = async () => Toast.Info("卸载成功"),
|
|
219
|
-
}).Forget();
|
|
220
|
-
`;
|
|
221
|
-
const snippets = extractor.extractStrings(code);
|
|
222
152
|
{
|
|
223
|
-
let
|
|
224
|
-
|
|
225
|
-
expect(
|
|
226
|
-
|
|
227
|
-
expect(
|
|
228
|
-
expect(
|
|
229
|
-
|
|
230
|
-
]);
|
|
231
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
153
|
+
let snippet = snippets[5];
|
|
154
|
+
expect(snippet.originalIndex).toBe(code.indexOf('$"Hello, {name}!"'));
|
|
155
|
+
expect(snippet.originalCode).toBe('$"Hello, {name}!"');
|
|
156
|
+
// `m_btn_fxx_wf` 符合 `m_btn_` 开头的条件
|
|
157
|
+
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
158
|
+
expect(snippet.literals).toContain('Hello, {0}!');
|
|
159
|
+
expect(snippet.isChanged).toBe(true);
|
|
232
160
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}).Forget();
|
|
240
|
-
`;
|
|
161
|
+
expect(snippets.length).toBe(6);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// 测试用 `+` 连接的字符串表达式, 确保用 `+` 符号拼接的字符串表达式被整体处理, 从中提取字符串表达式信息, 而不是分别处理 `+` 两边每个字符串表达式; 并且给 `+` 连接的每个成分追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式
|
|
165
|
+
test('should handle string concatenation', () => {
|
|
166
|
+
const code = 'var label2 = "Hello, " + name + "!";';
|
|
241
167
|
const snippets = extractor.extractStrings(code);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
247
|
-
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
248
|
-
expect(targetSnippet.literals).toEqual([
|
|
249
|
-
'卸载成功'
|
|
250
|
-
]);
|
|
251
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
252
|
-
}
|
|
253
|
-
})
|
|
168
|
+
|
|
169
|
+
expect(snippets.length).toBe(1);
|
|
170
|
+
expect(snippets[0].originalCode).toBe('"Hello, " + name + "!"');
|
|
171
|
+
expect(snippets[0].convertedCode).toBe('"Hello, ".TR() + name.TR() + "!".TR()');
|
|
254
172
|
});
|
|
255
173
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const code =
|
|
259
|
-
//上锁
|
|
260
|
-
case (int)State.Lock:
|
|
261
|
-
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
262
|
-
break;
|
|
263
|
-
`;
|
|
174
|
+
// 测试 `xxx.text = yyy;` 形式的赋值语句, 确保将 `yyy` 中的字符串表达式信息提取出来, 并追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式; 其中 `xxx`和`yyy` 代表某段C#字面量, 可以是对象、字符串、或其他表达式
|
|
175
|
+
test('should handle .text = assignments with function calls', () => {
|
|
176
|
+
const code = 'label.text = Func();';
|
|
264
177
|
const snippets = extractor.extractStrings(code);
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
})
|
|
276
|
-
test('should handle comment boundary 2', () => {
|
|
277
|
-
const code = `
|
|
278
|
-
// klwjfe
|
|
279
|
-
namespace TestNamespace{
|
|
280
|
-
// lkwjfe
|
|
281
|
-
public class FK{
|
|
282
|
-
// klwf
|
|
283
|
-
public void TestM(){
|
|
284
|
-
// 模拟状态变量
|
|
285
|
-
var _state = (int)State.Lock;
|
|
286
|
-
// 模拟土地ID变量
|
|
287
|
-
switch (_state){
|
|
288
|
-
//上锁
|
|
289
|
-
case (int)State.Lock:
|
|
290
|
-
// lkwjefl
|
|
291
|
-
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
292
|
-
// klwejf
|
|
293
|
-
break;
|
|
294
|
-
// lkwjf
|
|
295
|
-
}
|
|
296
|
-
// klwjfel
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
`;
|
|
178
|
+
|
|
179
|
+
expect(snippets.length).toBe(1);
|
|
180
|
+
expect(snippets[0].originalCode).toBe('Func()');
|
|
181
|
+
expect(snippets[0].convertedCode).toBe('Func().TR()');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// 测试 `xxx.text = xxx + xxx;` 形式的赋值语句, 确保将 `xxx.text` 中的 `xxx` 字符串表达式提取出来, 并追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式; 其中 `xxx`和`yyy` 代表某段C#表达式, 可以是对象、字符串、或其他表达式
|
|
185
|
+
test('should handle .text = assignments with multiple function calls', () => {
|
|
186
|
+
const code = 'label.text = Func() + Func();';
|
|
301
187
|
const snippets = extractor.extractStrings(code);
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
})
|
|
313
|
-
test('should handle comment boundary 3', () => {
|
|
314
|
-
const code = `
|
|
315
|
-
// klwjfe
|
|
316
|
-
namespace TestNamespace{
|
|
317
|
-
// lkwjfe
|
|
318
|
-
public class FK{
|
|
319
|
-
// wlkjelj
|
|
320
|
-
private int Llkwe = 23;
|
|
321
|
-
// lkjlkj
|
|
322
|
-
private int Dwekl { get; set; } = 23;
|
|
323
|
-
// jklwef
|
|
324
|
-
private static int Dwekl { get; set; } = 23;
|
|
325
|
-
// lkwjeflk
|
|
326
|
-
public static void TestM(){}
|
|
327
|
-
// wesd
|
|
328
|
-
public static void TestM()
|
|
329
|
-
{
|
|
330
|
-
}
|
|
331
|
-
// wesd
|
|
332
|
-
public static void TestM(){
|
|
333
|
-
}
|
|
334
|
-
// klwf
|
|
335
|
-
public void TestM(){
|
|
336
|
-
// 模拟状态变量
|
|
337
|
-
var _state = (int)State.Lock;
|
|
338
|
-
// 模拟土地ID变量
|
|
339
|
-
switch (_state){
|
|
340
|
-
//上锁
|
|
341
|
-
case (int)State.Lock:
|
|
342
|
-
// lkwjefl
|
|
343
|
-
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
344
|
-
// klwejf
|
|
345
|
-
break;
|
|
346
|
-
// lkwjf
|
|
347
|
-
}
|
|
348
|
-
// klwjfel
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
`;
|
|
188
|
+
|
|
189
|
+
expect(snippets.length).toBe(1);
|
|
190
|
+
expect(snippets[0].originalCode).toBe('Func() + Func()');
|
|
191
|
+
expect(snippets[0].convertedCode).toBe('Func().TR() + Func().TR()');
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// 测试 `xxx.text = yyy;` 形式的赋值语句, 确保将 `yyy` 中的 `xxx` 内插字符串提取出来, 并转换为 `Tr.Format(...)` 形式; 其中 `xxx`和`yyy` 代表某段C#表达式, 可以是对象、字符串、或其他表达式
|
|
195
|
+
test('should handle .text = assignments with string templates', () => {
|
|
196
|
+
const code = 'label.text = $"pre{Func()}sub";';
|
|
353
197
|
const snippets = extractor.extractStrings(code);
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
expect(targetSnippet.literals).toEqual([
|
|
360
|
-
'灵田{0}级解锁'
|
|
361
|
-
]);
|
|
362
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
363
|
-
}
|
|
364
|
-
})
|
|
198
|
+
|
|
199
|
+
expect(snippets.length).toBe(1);
|
|
200
|
+
expect(snippets[0].originalCode).toBe('$"pre{Func()}sub"');
|
|
201
|
+
expect(snippets[0].literals).toContain('pre{0}sub');
|
|
202
|
+
expect(snippets[0].convertedCode).toBe('Tr.Format("pre{0}sub", Func())');
|
|
365
203
|
});
|
|
366
204
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
const code =
|
|
370
|
-
infoStr += $"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n";
|
|
371
|
-
infoStr += $"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n";
|
|
372
|
-
`;
|
|
205
|
+
// 测试从内插字符串中提取字符串表达式信息时, 需要注意转换和捕获内插字符串格式参数, 内插字符串和对应格式参数参考: `https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/tokens/interpolated`
|
|
206
|
+
test('should handle .text = assignments with string.Format', () => {
|
|
207
|
+
const code = 'label.text = string.Format("pre{0:F2}{1}", Func(), "sub") + other;';
|
|
373
208
|
const snippets = extractor.extractStrings(code);
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
})
|
|
385
|
-
test('should handle complex string 2', () => {
|
|
386
|
-
const code = `
|
|
387
|
-
infoStr += Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType);
|
|
388
|
-
infoStr += $"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n";
|
|
389
|
-
`;
|
|
209
|
+
|
|
210
|
+
expect(snippets.length).toBe(1);
|
|
211
|
+
expect(snippets[0].originalCode).toBe('string.Format("pre{0:F2}{1}", Func(), "sub") + other');
|
|
212
|
+
expect(snippets[0].literals).toContain('pre{0:F2}{1}');
|
|
213
|
+
expect(snippets[0].literals).toContain('sub');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// 测试用 `+` 连接的字符串表达式, 确保用 `+` 符号拼接的字符串表达式被整体处理, 从中提取字符串表达式信息, 而不是分别处理 `+` 两边每个字符串表达式; 并且给 `+` 连接的每个成分追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式或进一步递归处理
|
|
217
|
+
test('should handle complex concatenation with existing .TR() calls', () => {
|
|
218
|
+
const code = 'var hello3 = "Hello, ".TR() + name.TR() + obj2.name.TR() + obj2.nam1_e.Fn1().Prop + "!";';
|
|
390
219
|
const snippets = extractor.extractStrings(code);
|
|
391
|
-
{
|
|
392
|
-
let targetSnippet = snippets[0];
|
|
393
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`));
|
|
394
|
-
expect(targetSnippet.originalCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
395
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
396
|
-
expect(targetSnippet.literals).toEqual([
|
|
397
|
-
'伤害类型: [color={0}][b]{1}[/b][/color]\n'
|
|
398
|
-
]);
|
|
399
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
400
|
-
}
|
|
401
|
-
})
|
|
402
|
-
test('should handle complex string 4', () => {
|
|
403
|
-
const code = `
|
|
404
|
-
private void OnBtnIaa(EventContext context)
|
|
405
|
-
{
|
|
406
|
-
var iaaConfig = IAAConfigTable.GetConfigById((int)IAAId.境界失败_加速冷却);
|
|
407
|
-
if (iaaConfig == null)
|
|
408
|
-
{
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
220
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
221
|
+
expect(snippets.length).toBe(1);
|
|
222
|
+
expect(snippets[0].originalCode).toBe('"Hello, ".TR() + name.TR() + obj2.name.TR() + obj2.nam1_e.Fn1().Prop + "!"');
|
|
223
|
+
expect(snippets[0].convertedCode).toBe('"Hello, ".TR() + name.TR() + obj2.name.TR() + obj2.nam1_e.Fn1().Prop.TR() + "!".TR()');
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// 测试处理包含转义引号的字符串表达式, 确保能正确提取和转换转义引号, 而不会影响字符串边界的正常解析
|
|
227
|
+
test('should handle escaped quotes in strings', () => {
|
|
228
|
+
const code = 'Debug.Log("aaa\\\"bbb\\\"c\\\"d\\\\\\"cc");';
|
|
416
229
|
const snippets = extractor.extractStrings(code);
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
'观看视频后\n等待时间减少{0}分钟'
|
|
424
|
-
]);
|
|
425
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
426
|
-
}
|
|
427
|
-
})
|
|
230
|
+
|
|
231
|
+
expect(snippets.length).toBe(1);
|
|
232
|
+
expect(snippets[0].originalCode).toBe('"aaa\\\"bbb\\\"c\\\"d\\\\\\"cc"');
|
|
233
|
+
expect(snippets[0].convertedCode).toBe('"aaa\\\"bbb\\\"c\\\"d\\\\\\"cc"');
|
|
234
|
+
// 由于JavaScript字符串转义的复杂性,我们只检查是否提取了字符串
|
|
235
|
+
expect(snippets[0].literals).toEqual(['aaa\\\"bbb\\\"c\\\"d\\\\\\"cc']);
|
|
428
236
|
});
|
|
429
237
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const code =
|
|
433
|
-
else if (battleModel.CurGameType == BattleModel.GameType.Teamwork)
|
|
434
|
-
{
|
|
435
|
-
//合作模式显示队友名称
|
|
436
|
-
m_text_otherName.text = battleModel.TeammatePlayerData?.Name ?? "";
|
|
437
|
-
}
|
|
438
|
-
`;
|
|
238
|
+
// 测试处理包含 `+` 连接的字符串表达式, 需要给 `+` 连接的每个成分追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式或进一步递归处理
|
|
239
|
+
test('should capture statement boundaries correctly', () => {
|
|
240
|
+
const code = 'obj.text = "Test property" + "Test property2";';
|
|
439
241
|
const snippets = extractor.extractStrings(code);
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
242
|
+
|
|
243
|
+
expect(snippets.length).toBe(1);
|
|
244
|
+
expect(snippets[0].originalCode).toBe('"Test property" + "Test property2"');
|
|
245
|
+
expect(snippets[0].convertedCode).toBe('"Test property".TR() + "Test property2".TR()');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// 测试处理包含多个语句的C#代码, 确保能从各个语句中正确提取和转换每个语句中的字符串表达式, 而不会影响其他语句的正常解析
|
|
249
|
+
test('should handle multiple statements', () => {
|
|
250
|
+
const code = 'obj1.text = "Hello"; obj2.text = "World";';
|
|
251
|
+
const snippets = extractor.extractStrings(code);
|
|
252
|
+
|
|
253
|
+
expect(snippets.length).toBe(2);
|
|
254
|
+
expect(snippets[0].originalCode).toBe('"Hello"');
|
|
255
|
+
expect(snippets[0].convertedCode).toBe('"Hello".TR()');
|
|
256
|
+
expect(snippets[1].originalCode).toBe('"World"');
|
|
257
|
+
expect(snippets[1].convertedCode).toBe('"World".TR()');
|
|
451
258
|
});
|
|
452
259
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
const code =
|
|
260
|
+
// 测试处理作为函数参数的内插字符串表达式, 确保能从内插字符串中提取字符串表达式信息, 并转换为 `Tr.Format(...)` 形式
|
|
261
|
+
test('should extract and convert string templates', () => {
|
|
262
|
+
const code = 'Ljk.Ilk($"Hello, {name}!");';
|
|
456
263
|
const snippets = extractor.extractStrings(code);
|
|
457
264
|
|
|
458
|
-
// 验证提取的片段数量
|
|
459
265
|
expect(snippets.length).toBeGreaterThan(0);
|
|
266
|
+
const snippet = snippets[0];
|
|
267
|
+
expect(snippet.originalCode).toBe('$"Hello, {name}!"');
|
|
268
|
+
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
269
|
+
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
270
|
+
expect(snippet.isChanged).toBe(true);
|
|
271
|
+
});
|
|
460
272
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
expect(targetSnippet.literals).toEqual([
|
|
465
|
-
'+={0}'
|
|
466
|
-
]);
|
|
467
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
468
|
-
})
|
|
469
|
-
test('should handle duplicate tr handle 2', () => {
|
|
470
|
-
const code = `infoStr += $"={colorCode}";`
|
|
273
|
+
// 测试处理 `string.Format` 调用, 确保能将其转换为 `Tr.Format(...)` 形式, 并正确提取字符串表达式信息
|
|
274
|
+
test('should convert string.Format to Tr.Format', () => {
|
|
275
|
+
const code = 'string.Format("Hello, {0}!", name);';
|
|
471
276
|
const snippets = extractor.extractStrings(code);
|
|
472
277
|
|
|
473
|
-
// 验证提取的片段数量
|
|
474
278
|
expect(snippets.length).toBeGreaterThan(0);
|
|
279
|
+
const snippet = snippets[0];
|
|
280
|
+
expect(snippet.originalCode).toBe('string.Format("Hello, {0}!", name)');
|
|
281
|
+
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
282
|
+
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
283
|
+
expect(snippet.isChanged).toBe(true);
|
|
284
|
+
});
|
|
475
285
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
expect(targetSnippet.literals).toEqual([
|
|
480
|
-
'={0}'
|
|
481
|
-
]);
|
|
482
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
483
|
-
})
|
|
484
|
-
test('should handle duplicate tr handle 3', () => {
|
|
485
|
-
const code = `infoStr += $"+={colorCode}";`
|
|
286
|
+
// 测试处理 `xxx.text = yyy;` 形式赋值语句, 以 `.text =` 给 `text` 成员赋值的表达式中, `yyy` 部分必定是字符串表达式, 需要从 `yyy` 中正确提取字符串表达式信息, 并给普通字符串表达式追加 `.TR()` 或者让内插字符串转换为 `Tr.Format(...)` 形式
|
|
287
|
+
test('should handle .text = assignments', () => {
|
|
288
|
+
const code = 'label.text = "Test";';
|
|
486
289
|
const snippets = extractor.extractStrings(code);
|
|
487
290
|
|
|
488
|
-
// 验证提取的片段数量
|
|
489
291
|
expect(snippets.length).toBeGreaterThan(0);
|
|
292
|
+
const snippet = snippets[0];
|
|
293
|
+
expect(snippet.originalCode).toBe('"Test"');
|
|
294
|
+
expect(snippet.convertedCode).toBe('"Test".TR()');
|
|
295
|
+
expect(snippet.literals).toEqual(['Test']);
|
|
296
|
+
expect(snippet.isChanged).toBe(true);
|
|
297
|
+
});
|
|
490
298
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
expect(targetSnippet.literals).toEqual([
|
|
495
|
-
'+={0}'
|
|
496
|
-
]);
|
|
497
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
498
|
-
})
|
|
499
|
-
test('should handle duplicate tr handle 4', () => {
|
|
500
|
-
const code = `infoStr += $"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n";`
|
|
299
|
+
// 测试处理包含 `+` 连接的字符串表达式, 需要给 `+` 连接的每个成分追加 `.TR()` 或者转换为 `Tr.Format(...)` 形式或进一步递归处理
|
|
300
|
+
test('should handle string concatenations', () => {
|
|
301
|
+
const code = 'var wkleee = "Hello, " + name + "!";';
|
|
501
302
|
const snippets = extractor.extractStrings(code);
|
|
502
303
|
|
|
503
|
-
// 验证提取的片段数量
|
|
504
304
|
expect(snippets.length).toBeGreaterThan(0);
|
|
305
|
+
const snippet = snippets[0];
|
|
306
|
+
expect(snippet.originalCode).toBe('"Hello, " + name + "!"');
|
|
307
|
+
expect(snippet.convertedCode).toBe('"Hello, ".TR() + name.TR() + "!".TR()');
|
|
308
|
+
expect(snippet.literals).toEqual(['Hello, ', '!']);
|
|
309
|
+
expect(snippet.isChanged).toBe(true);
|
|
310
|
+
});
|
|
505
311
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
]
|
|
512
|
-
expect(
|
|
513
|
-
|
|
312
|
+
// 测试处理 `+` 连接的字符串表达式时, 确保不会给已经包含 `.TR()` 的字符串表达式再次追加 `.TR()`
|
|
313
|
+
test('should not add .TR() to strings already having it', () => {
|
|
314
|
+
const code = 'var wkle = "Hello".TR();';
|
|
315
|
+
const snippets = extractor.extractStrings(code);
|
|
316
|
+
|
|
317
|
+
const snippet = snippets[0];
|
|
318
|
+
expect(snippet.originalCode).toBe('"Hello".TR()');
|
|
319
|
+
expect(snippet.convertedCode).toBe('"Hello".TR()');
|
|
320
|
+
expect(snippet.literals).toEqual(['Hello']);
|
|
321
|
+
expect(snippet.isChanged).toBe(false);
|
|
514
322
|
});
|
|
515
323
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const code =
|
|
324
|
+
// 测试处理复杂的 `.text =` 赋值语句, 确保能正确处理包含 `string.Format` 调用和 `+` 连接的字符串表达式, 并转换为 `Tr.Format(...)` 形式或进一步递归处理
|
|
325
|
+
test('should handle complex text assignments', () => {
|
|
326
|
+
const code = 'label.text = string.Format("pre{0}sub", Func()) + other;';
|
|
519
327
|
const snippets = extractor.extractStrings(code);
|
|
520
328
|
|
|
521
|
-
|
|
522
|
-
expect(
|
|
523
|
-
|
|
329
|
+
const snippet = snippets[0];
|
|
330
|
+
expect(snippet.originalCode).toBe('string.Format("pre{0}sub", Func()) + other');
|
|
331
|
+
expect(snippet.convertedCode).toBe('Tr.Format("pre{0}sub", Func()) + other.TR()');
|
|
332
|
+
expect(snippet.literals).toEqual(['pre{0}sub']);
|
|
333
|
+
expect(snippet.isChanged).toBe(true);
|
|
334
|
+
});
|
|
524
335
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
"已购买"
|
|
530
|
-
]);
|
|
531
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
336
|
+
// 测试处理转义字符串, 确保能正确处理包含转义字符的字符串表达式, 并给普通字符串表达式追加 `.TR()` 或者让内插字符串转换为 `Tr.Format(...)` 形式
|
|
337
|
+
test('should handle escaped strings', () => {
|
|
338
|
+
const code = 'a.text = "aaa\\"bbb\\"c\\"d\\\\\\"cc";';
|
|
339
|
+
const snippets = extractor.extractStrings(code);
|
|
532
340
|
|
|
533
|
-
|
|
534
|
-
expect(
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
341
|
+
const snippet = snippets[0];
|
|
342
|
+
expect(snippet.originalCode).toBe('"aaa\\"bbb\\"c\\"d\\\\\\"cc"');
|
|
343
|
+
expect(snippet.convertedCode).toBe('"aaa\\"bbb\\"c\\"d\\\\\\"cc".TR()');
|
|
344
|
+
expect(snippet.literals).toEqual(['aaa\\"bbb\\"c\\"d\\\\\\"cc']);
|
|
345
|
+
expect(snippet.isChanged).toBe(true);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// 测试处理 `@$""` 和 `$@""` 格式的字符串表达式, 确保能将其转换为 `Tr.Format(...)` 形式, 并正确提取字符串表达式信息
|
|
349
|
+
test('should handle @$"" and $@"" formats', () => {
|
|
350
|
+
const code = 'Fcx.Kjl(@$"Hello, {name}!");';
|
|
538
351
|
const snippets = extractor.extractStrings(code);
|
|
539
352
|
|
|
540
|
-
|
|
541
|
-
expect(
|
|
542
|
-
expect(
|
|
543
|
-
expect(
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
')'
|
|
547
|
-
]);
|
|
548
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
353
|
+
const snippet = snippets[0];
|
|
354
|
+
expect(snippet.originalCode).toBe('@$"Hello, {name}!"');
|
|
355
|
+
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
356
|
+
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
357
|
+
expect(snippet.isChanged).toBe(true);
|
|
358
|
+
});
|
|
549
359
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const code =
|
|
360
|
+
// 测试处理函数调用时, 确保能正确提取参数中的字符串表达式, 不需要给字符串表达式追加 `.TR()` 或 转换为 `Tr.Format(...)` 形式, 除非遇到由 `+` 连接的字符串表达式
|
|
361
|
+
test('should handle function calls with string arguments', () => {
|
|
362
|
+
const code = 'CallFunc("Hello", "World");';
|
|
553
363
|
const snippets = extractor.extractStrings(code);
|
|
364
|
+
{
|
|
365
|
+
const snippet = snippets[0];
|
|
366
|
+
expect(snippet.originalCode).toBe('"Hello"');
|
|
367
|
+
expect(snippet.convertedCode).toBe('"Hello"');
|
|
368
|
+
expect(snippet.literals).toEqual(['Hello']);
|
|
369
|
+
expect(snippet.isChanged).toBe(false);
|
|
370
|
+
}
|
|
371
|
+
{
|
|
554
372
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
373
|
+
const snippet = snippets[1];
|
|
374
|
+
expect(snippet.originalCode).toBe('"World"');
|
|
375
|
+
expect(snippet.convertedCode).toBe('"World"');
|
|
376
|
+
expect(snippet.literals).toEqual(['World']);
|
|
377
|
+
expect(snippet.isChanged).toBe(false);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
563
380
|
|
|
564
|
-
|
|
381
|
+
// 测试处理 `.text =` 赋值语句时, 确保能正确处理包含 `Tr.Format(...)` 调用的字符串表达式, 并给普通字符串表达式追加 `.TR()` 或者让内插字符串转换为 `Tr.Format(...)` 形式
|
|
382
|
+
test('should handle .text = with Tr.Format', () => {
|
|
383
|
+
const code = 'label.text = Tr.Format("pre", Func(), "sub") + other;';
|
|
384
|
+
const snippets = extractor.extractStrings(code);
|
|
385
|
+
|
|
386
|
+
const snippet = snippets[0];
|
|
387
|
+
expect(snippet.originalCode).toBe('Tr.Format("pre", Func(), "sub") + other');
|
|
388
|
+
expect(snippet.convertedCode).toBe('Tr.Format("pre", Func(), "sub") + other.TR()');
|
|
389
|
+
expect(snippet.literals).toEqual(['pre', 'sub']);
|
|
390
|
+
expect(snippet.isChanged).toBe(true);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
// 测试处理 `.text =` 赋值语句时, 确保能正确处理包含 `Tr.Format(...)` 调用的字符串表达式, 并给普通字符串表达式追加 `.TR()` 或者让内插字符串转换为 `Tr.Format(...)` 形式, 除非遇到由 `+` 连接的字符串表达式
|
|
394
|
+
test('should handle .text = with Tr.Format 2', () => {
|
|
395
|
+
const code = 'm_text_lastAward.text = $"[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]";';
|
|
396
|
+
const snippets = extractor.extractStrings(code);
|
|
397
|
+
|
|
398
|
+
const snippet = snippets[0];
|
|
399
|
+
expect(snippet.originalCode).toBe('$"[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]"');
|
|
400
|
+
expect(snippet.convertedCode).toBe('$"[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]".TR()');
|
|
401
|
+
expect(snippet.literals).toEqual(['[color=#FFFFFF]上期奖励:[/color][color=#FFE97E][/color][color=#FFFFFF]暂无获奖[/color]']);
|
|
402
|
+
expect(snippet.isChanged).toBe(true);
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// 处理C#多行语句
|
|
406
|
+
test('should handle non string assignment 1', () => {
|
|
407
|
+
const code = 'var d1 = 12;var d2 = 13;var d3 = d1 + d2;var aa = "aaa";';
|
|
408
|
+
const snippets = extractor.extractStrings(code);
|
|
409
|
+
{
|
|
410
|
+
const snippet = snippets[0];
|
|
411
|
+
expect(snippet.originalCode).toBe('"aaa"');
|
|
412
|
+
expect(snippet.convertedCode).toBe('"aaa"');
|
|
413
|
+
expect(snippet.literals).toEqual(['aaa']);
|
|
414
|
+
expect(snippet.isChanged).toBe(false);
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// 处理C#多行语句
|
|
419
|
+
test('should handle non string assignment 2', () => {
|
|
420
|
+
const code = 'var d3 = d1 + d2;var aa = "aaa";';
|
|
421
|
+
const snippets = extractor.extractStrings(code);
|
|
422
|
+
{
|
|
423
|
+
const snippet = snippets[0];
|
|
424
|
+
expect(snippet.originalCode).toBe('"aaa"');
|
|
425
|
+
expect(snippet.convertedCode).toBe('"aaa"');
|
|
426
|
+
expect(snippet.literals).toEqual(['aaa']);
|
|
427
|
+
expect(snippet.isChanged).toBe(false);
|
|
428
|
+
}
|
|
565
429
|
});
|
|
566
430
|
|
|
567
|
-
|
|
568
|
-
|
|
431
|
+
// 处理C#多行语句
|
|
432
|
+
test('should handle multilne content 1', () => {
|
|
569
433
|
const code = 'var aa = "aaa";\nvar bb = "bbb";\nvar cc = "ccc";';
|
|
570
434
|
const snippets = extractor.extractStrings(code);
|
|
571
435
|
{
|
|
@@ -589,8 +453,10 @@ namespace TestNamespace{
|
|
|
589
453
|
expect(snippet.literals).toEqual(['ccc']);
|
|
590
454
|
expect(snippet.isChanged).toBe(false);
|
|
591
455
|
}
|
|
592
|
-
})
|
|
593
|
-
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// 处理C#多行语句
|
|
459
|
+
test('should handle multilne content 2', () => {
|
|
594
460
|
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;';
|
|
595
461
|
const snippets = extractor.extractStrings(code);
|
|
596
462
|
{
|
|
@@ -663,8 +529,10 @@ namespace TestNamespace{
|
|
|
663
529
|
expect(snippet.literals).toEqual(['jjj']);
|
|
664
530
|
expect(snippet.isChanged).toBe(true);
|
|
665
531
|
}
|
|
666
|
-
})
|
|
667
|
-
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
// 处理C#多行语句
|
|
535
|
+
test('should handle multilne content 3', () => {
|
|
668
536
|
const code = 'label.text = Tr.Format("pre", Func(), "sub") + other;\nlabel2.text = Tr.Format("pre2", Func(), "sub2") + other2;';
|
|
669
537
|
const snippets = extractor.extractStrings(code);
|
|
670
538
|
{
|
|
@@ -681,8 +549,10 @@ namespace TestNamespace{
|
|
|
681
549
|
expect(snippet.literals).toEqual(['pre2', 'sub2']);
|
|
682
550
|
expect(snippet.isChanged).toBe(true);
|
|
683
551
|
}
|
|
684
|
-
})
|
|
685
|
-
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
// 处理C#多行语句
|
|
555
|
+
test('should handle multilne content 4', () => {
|
|
686
556
|
const code = 'label.text =\n Tr.Format(\n\t"pre", Func(),\n\t\t "sub") + other;';
|
|
687
557
|
const snippets = extractor.extractStrings(code);
|
|
688
558
|
{
|
|
@@ -692,8 +562,10 @@ namespace TestNamespace{
|
|
|
692
562
|
expect(snippet.literals).toEqual(['pre', 'sub']);
|
|
693
563
|
expect(snippet.isChanged).toBe(true);
|
|
694
564
|
}
|
|
695
|
-
})
|
|
696
|
-
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// 处理C#多行语句
|
|
568
|
+
test('should handle multilne content 5', () => {
|
|
697
569
|
const code = `
|
|
698
570
|
// 注释中无字符串表达式时, 不需要包含在捕获部分里
|
|
699
571
|
m_text_name.text = cardTable.Name;
|
|
@@ -706,8 +578,10 @@ namespace TestNamespace{
|
|
|
706
578
|
expect(snippet.literals).toEqual([]);
|
|
707
579
|
expect(snippet.isChanged).toBe(true);
|
|
708
580
|
}
|
|
709
|
-
})
|
|
710
|
-
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
// 处理C#多行语句
|
|
584
|
+
test('should handle multilne content 6', () => {
|
|
711
585
|
const code = `
|
|
712
586
|
if (condition)
|
|
713
587
|
{
|
|
@@ -723,8 +597,10 @@ namespace TestNamespace{
|
|
|
723
597
|
expect(snippet.originalIndex).toBe(code.indexOf('"卸载成功"'));
|
|
724
598
|
expect(snippet.isChanged).toBe(false);
|
|
725
599
|
}
|
|
726
|
-
})
|
|
727
|
-
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
// 处理C#多行语句
|
|
603
|
+
test('should handle multilne content 7', () => {
|
|
728
604
|
const code = `
|
|
729
605
|
while (condition)
|
|
730
606
|
{
|
|
@@ -740,8 +616,10 @@ namespace TestNamespace{
|
|
|
740
616
|
expect(snippet.originalIndex).toBe(code.indexOf('"卸载成功"'));
|
|
741
617
|
expect(snippet.isChanged).toBe(false);
|
|
742
618
|
}
|
|
743
|
-
})
|
|
744
|
-
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
// 处理C#多行语句
|
|
622
|
+
test('should handle multilne content 8', () => {
|
|
745
623
|
const code = `
|
|
746
624
|
for (scope;condition;continuex)
|
|
747
625
|
{
|
|
@@ -756,8 +634,10 @@ namespace TestNamespace{
|
|
|
756
634
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
757
635
|
expect(snippet.isChanged).toBe(false);
|
|
758
636
|
}
|
|
759
|
-
})
|
|
760
|
-
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
// 处理C#多行语句
|
|
640
|
+
test('should handle multilne content 9', () => {
|
|
761
641
|
const code = `
|
|
762
642
|
{
|
|
763
643
|
KK3.Ca3("卸载成功");
|
|
@@ -771,8 +651,10 @@ namespace TestNamespace{
|
|
|
771
651
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
772
652
|
expect(snippet.isChanged).toBe(false);
|
|
773
653
|
}
|
|
774
|
-
})
|
|
775
|
-
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
// 处理C#多行语句
|
|
657
|
+
test('should handle multilne content 10', () => {
|
|
776
658
|
const code = `
|
|
777
659
|
var lambda1 = () => {
|
|
778
660
|
LJN4.Fn4("卸载成功");
|
|
@@ -786,8 +668,10 @@ namespace TestNamespace{
|
|
|
786
668
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
787
669
|
expect(snippet.isChanged).toBe(false);
|
|
788
670
|
}
|
|
789
|
-
})
|
|
790
|
-
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
// 处理C#多行语句
|
|
674
|
+
test('should handle multilne content 11', () => {
|
|
791
675
|
const code = `
|
|
792
676
|
void lambda1() {
|
|
793
677
|
KK5.Call5("卸载成功");
|
|
@@ -801,8 +685,10 @@ namespace TestNamespace{
|
|
|
801
685
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
802
686
|
expect(snippet.isChanged).toBe(false);
|
|
803
687
|
}
|
|
804
|
-
})
|
|
805
|
-
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
// 处理C#多行语句
|
|
691
|
+
test('should handle multilne content 12', () => {
|
|
806
692
|
const code = `
|
|
807
693
|
//星级
|
|
808
694
|
m_list_star.RemoveChildrenToPool();
|
|
@@ -827,8 +713,10 @@ namespace TestNamespace{
|
|
|
827
713
|
expect(snippet.literals).toEqual(['{0}阶']);
|
|
828
714
|
expect(snippet.isChanged).toBe(false);
|
|
829
715
|
}
|
|
830
|
-
})
|
|
831
|
-
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
// 处理C#多行语句
|
|
719
|
+
test('should handle multilne content 13', () => {
|
|
832
720
|
const code = `
|
|
833
721
|
Toast.Info("卸载成功");
|
|
834
722
|
Toast.Info("卸载成功");
|
|
@@ -850,8 +738,10 @@ namespace TestNamespace{
|
|
|
850
738
|
expect(snippet.literals).toEqual(['卸载成功']);
|
|
851
739
|
expect(snippet.isChanged).toBe(false);
|
|
852
740
|
}
|
|
853
|
-
})
|
|
854
|
-
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
// 处理C#多行语句
|
|
744
|
+
test('should handle multilne content 14', () => {
|
|
855
745
|
const code = readFileSync('./test/MainSutraDetailDialog.cs', 'utf8');
|
|
856
746
|
const snippets = extractor.extractStrings(code);
|
|
857
747
|
|
|
@@ -1030,8 +920,10 @@ namespace TestNamespace{
|
|
|
1030
920
|
expect(snippets[21].convertedCode).toBe('"卸载成功"');
|
|
1031
921
|
expect(snippets[21].literals).toEqual(['卸载成功']);
|
|
1032
922
|
expect(snippets[21].isChanged).toBe(false);
|
|
1033
|
-
})
|
|
1034
|
-
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
// 处理C#多行语句
|
|
926
|
+
test('should handle multilne content 15', () => {
|
|
1035
927
|
const code = readFileSync('./test/GuildDonateDialog.cs', 'utf8');
|
|
1036
928
|
const snippets = extractor.extractStrings(code);
|
|
1037
929
|
|
|
@@ -1052,8 +944,41 @@ namespace TestNamespace{
|
|
|
1052
944
|
expect(targetSnippet.isChanged).toBe(true);
|
|
1053
945
|
}
|
|
1054
946
|
|
|
1055
|
-
})
|
|
1056
|
-
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
// 处理C#普通字符串包含 `//` 的情形
|
|
950
|
+
test('should handle string with `//`', () => {
|
|
951
|
+
const code = `m_btn_paid.text = "//";`
|
|
952
|
+
const snippets = extractor.extractStrings(code);
|
|
953
|
+
|
|
954
|
+
// 验证提取的片段数量
|
|
955
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
956
|
+
|
|
957
|
+
let targetSnippet = snippets[0];
|
|
958
|
+
expect(targetSnippet.originalCode).toBe(`"//"`);
|
|
959
|
+
expect(targetSnippet.convertedCode).toBe(`"//".TR()`);
|
|
960
|
+
expect(targetSnippet.literals).toEqual(['//']);
|
|
961
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
962
|
+
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
// 处理C# `+=` 形式赋值语句
|
|
966
|
+
test('should handle string template with format specifier', () => {
|
|
967
|
+
const code = `infoStr += $"最终抗性: {resistReduce:F}\\n";`
|
|
968
|
+
const snippets = extractor.extractStrings(code);
|
|
969
|
+
|
|
970
|
+
// 验证提取的片段数量
|
|
971
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
972
|
+
|
|
973
|
+
let targetSnippet = snippets[0];
|
|
974
|
+
expect(targetSnippet.originalCode).toBe(`$"最终抗性: {resistReduce:F}\\n"`);
|
|
975
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("最终抗性: {0:F}\\n", resistReduce)`);
|
|
976
|
+
expect(targetSnippet.literals).toEqual(['最终抗性: {0:F}\\n']);
|
|
977
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
// 处理C#多行语句, 特别是包含 `\n` 的字符串
|
|
981
|
+
test('should handle multilne content 17', () => {
|
|
1057
982
|
const code = `
|
|
1058
983
|
infoStr += $"aaa: {aa}\n" +
|
|
1059
984
|
$"bbb = {bb}";
|
|
@@ -1073,8 +998,10 @@ namespace TestNamespace{
|
|
|
1073
998
|
'bbb = {0}'
|
|
1074
999
|
]);
|
|
1075
1000
|
expect(targetSnippet.isChanged).toBe(true);
|
|
1076
|
-
})
|
|
1077
|
-
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
// 处理C#多行语句, 特别是包含 `\\n` 的内插字符串
|
|
1004
|
+
test('should handle multilne content 19', () => {
|
|
1078
1005
|
const code = `
|
|
1079
1006
|
infoStr += $"aaa: {aa}\\n" +
|
|
1080
1007
|
$"bbb = {bb}";
|
|
@@ -1094,8 +1021,10 @@ namespace TestNamespace{
|
|
|
1094
1021
|
'bbb = {0}'
|
|
1095
1022
|
]);
|
|
1096
1023
|
expect(targetSnippet.isChanged).toBe(true);
|
|
1097
|
-
})
|
|
1098
|
-
|
|
1024
|
+
});
|
|
1025
|
+
|
|
1026
|
+
// 处理C#中多行字符串拼接成的字符串表达式
|
|
1027
|
+
test('should handle multilne content 18', () => {
|
|
1099
1028
|
const code = `
|
|
1100
1029
|
infoStr += "伤害公式: \\n" +
|
|
1101
1030
|
$"最终伤害[color={colorCode}][{(float)damageValue:F}][/color] = \\n" +
|
|
@@ -1139,92 +1068,324 @@ namespace TestNamespace{
|
|
|
1139
1068
|
'抗性减免[b][{7:F}]'
|
|
1140
1069
|
]);
|
|
1141
1070
|
expect(targetSnippet.isChanged).toBe(true);
|
|
1142
|
-
})
|
|
1143
1071
|
});
|
|
1144
1072
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
const code =
|
|
1073
|
+
// 处理C#中包含括号的内插字符串
|
|
1074
|
+
test('should handle bracket 1', () => {
|
|
1075
|
+
const code = `m_text_time.text = $"下一轮神兽出现倒计时: {Date.GetIntweerpolatedTime(ServerTimer.Instance.Time, _startGameStamp)}";`
|
|
1148
1076
|
const snippets = extractor.extractStrings(code);
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1077
|
+
|
|
1078
|
+
// 验证提取的片段数量
|
|
1079
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1080
|
+
|
|
1081
|
+
let targetSnippet = snippets[0];
|
|
1082
|
+
expect(targetSnippet.originalCode).toBe(`$"下一轮神兽出现倒计时: {Date.GetIntweerpolatedTime(ServerTimer.Instance.Time, _startGameStamp)}"`);
|
|
1083
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("下一轮神兽出现倒计时: {0}", Date.GetIntweerpolatedTime(ServerTimer.Instance.Time, _startGameStamp))`);
|
|
1084
|
+
expect(targetSnippet.literals).toEqual([
|
|
1085
|
+
'下一轮神兽出现倒计时: {0}'
|
|
1086
|
+
]);
|
|
1087
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
// 处理C#中包含括号的内插字符串
|
|
1091
|
+
test('should handle bracket 2', () => {
|
|
1092
|
+
const code = `m_text_time.text = $"神兽离去时间: {Date.FeGetInterpolatedTime(ServerTimer.Instance.Time, _endGameStamp)}";`
|
|
1159
1093
|
const snippets = extractor.extractStrings(code);
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1094
|
+
|
|
1095
|
+
// 验证提取的片段数量
|
|
1096
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1097
|
+
|
|
1098
|
+
let targetSnippet = snippets[0];
|
|
1099
|
+
expect(targetSnippet.originalCode).toBe(`$"神兽离去时间: {Date.FeGetInterpolatedTime(ServerTimer.Instance.Time, _endGameStamp)}"`);
|
|
1100
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("神兽离去时间: {0}", Date.FeGetInterpolatedTime(ServerTimer.Instance.Time, _endGameStamp))`);
|
|
1101
|
+
expect(targetSnippet.literals).toEqual([
|
|
1102
|
+
'神兽离去时间: {0}'
|
|
1103
|
+
]);
|
|
1104
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1168
1105
|
});
|
|
1169
1106
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
const code = `
|
|
1107
|
+
// 处理C#中包含括号的内插字符串
|
|
1108
|
+
test('should handle bracket 3', () => {
|
|
1109
|
+
const code = `desc += $"剩余{ToGetInterpolatedTime(_cardPoolData.FinishTime * 1000, ServerTimer.Instance.Time)}";`
|
|
1173
1110
|
const snippets = extractor.extractStrings(code);
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1111
|
+
|
|
1112
|
+
// 验证提取的片段数量
|
|
1113
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1114
|
+
|
|
1115
|
+
let targetSnippet = snippets[0];
|
|
1116
|
+
expect(targetSnippet.originalCode).toBe(`$"剩余{ToGetInterpolatedTime(_cardPoolData.FinishTime * 1000, ServerTimer.Instance.Time)}"`);
|
|
1117
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("剩余{0}", ToGetInterpolatedTime(_cardPoolData.FinishTime * 1000, ServerTimer.Instance.Time))`);
|
|
1118
|
+
expect(targetSnippet.literals).toEqual([
|
|
1119
|
+
'剩余{0}'
|
|
1120
|
+
]);
|
|
1121
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1122
|
+
});
|
|
1123
|
+
|
|
1124
|
+
// 处理C#中包含括号的内插字符串
|
|
1125
|
+
test('should handle bracket 4', () => {
|
|
1126
|
+
const code = `desc += $"剩余{ToGetInterpolatedTime(FF(_cardPoolData.FinishTime() * 1000, ServerTimer.Instance.Time()))}";`
|
|
1187
1127
|
const snippets = extractor.extractStrings(code);
|
|
1188
|
-
|
|
1189
|
-
|
|
1128
|
+
|
|
1129
|
+
// 验证提取的片段数量
|
|
1130
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1131
|
+
|
|
1132
|
+
let targetSnippet = snippets[0];
|
|
1133
|
+
expect(targetSnippet.originalCode).toBe(`$"剩余{ToGetInterpolatedTime(FF(_cardPoolData.FinishTime() * 1000, ServerTimer.Instance.Time()))}"`);
|
|
1134
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("剩余{0}", ToGetInterpolatedTime(FF(_cardPoolData.FinishTime() * 1000, ServerTimer.Instance.Time())))`);
|
|
1135
|
+
expect(targetSnippet.literals).toEqual([
|
|
1136
|
+
'剩余{0}'
|
|
1137
|
+
]);
|
|
1138
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
// 处理C#中包含`+=`符号的内插字符串
|
|
1142
|
+
test('should handle duplicate tr handle 1', () => {
|
|
1143
|
+
const code = `infoStr = $"+={colorCode}";`
|
|
1144
|
+
const snippets = extractor.extractStrings(code);
|
|
1145
|
+
|
|
1146
|
+
// 验证提取的片段数量
|
|
1147
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1148
|
+
|
|
1149
|
+
let targetSnippet = snippets[0];
|
|
1150
|
+
expect(targetSnippet.originalCode).toBe(`$"+={colorCode}"`);
|
|
1151
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("+={0}", colorCode)`);
|
|
1152
|
+
expect(targetSnippet.literals).toEqual([
|
|
1153
|
+
'+={0}'
|
|
1154
|
+
]);
|
|
1155
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
// 处理C# `+=` 形式的赋值语句后接 包含 `=` 符号的内插字符串
|
|
1159
|
+
test('should handle duplicate tr handle 2', () => {
|
|
1160
|
+
const code = `infoStr += $"={colorCode}";`
|
|
1161
|
+
const snippets = extractor.extractStrings(code);
|
|
1162
|
+
|
|
1163
|
+
// 验证提取的片段数量
|
|
1164
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1165
|
+
|
|
1166
|
+
let targetSnippet = snippets[0];
|
|
1167
|
+
expect(targetSnippet.originalCode).toBe(`$"={colorCode}"`);
|
|
1168
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("={0}", colorCode)`);
|
|
1169
|
+
expect(targetSnippet.literals).toEqual([
|
|
1170
|
+
'={0}'
|
|
1171
|
+
]);
|
|
1172
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1173
|
+
});
|
|
1174
|
+
|
|
1175
|
+
// 处理C# `+=` 形式的赋值语句后接 包含 `+=` 符号的内插字符串
|
|
1176
|
+
test('should handle duplicate tr handle 3', () => {
|
|
1177
|
+
const code = `infoStr += $"+={colorCode}";`
|
|
1178
|
+
const snippets = extractor.extractStrings(code);
|
|
1179
|
+
|
|
1180
|
+
// 验证提取的片段数量
|
|
1181
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1182
|
+
|
|
1183
|
+
let targetSnippet = snippets[0];
|
|
1184
|
+
expect(targetSnippet.originalCode).toBe(`$"+={colorCode}"`);
|
|
1185
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("+={0}", colorCode)`);
|
|
1186
|
+
expect(targetSnippet.literals).toEqual([
|
|
1187
|
+
'+={0}'
|
|
1188
|
+
]);
|
|
1189
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
// 处理C# `+=` 形式的赋值语句后接包含 `=`、`[`、`]`、`{`、`}`、`=` 等特殊符号的内插字符串
|
|
1193
|
+
test('should handle duplicate tr handle 4', () => {
|
|
1194
|
+
const code = `infoStr += $"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n";`
|
|
1195
|
+
const snippets = extractor.extractStrings(code);
|
|
1196
|
+
|
|
1197
|
+
// 验证提取的片段数量
|
|
1198
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1199
|
+
|
|
1200
|
+
let targetSnippet = snippets[0];
|
|
1201
|
+
expect(targetSnippet.originalCode).toBe(`$"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n"`);
|
|
1202
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
1203
|
+
expect(targetSnippet.literals).toEqual([
|
|
1204
|
+
'伤害类型: [color={0}][b]{1}[/b][/color]\n'
|
|
1205
|
+
]);
|
|
1206
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1207
|
+
});
|
|
1208
|
+
|
|
1209
|
+
// 处理C#中函数调用参数中包含普通字符串的情况, 函数参数需要拆分, 逐个参数捕获
|
|
1210
|
+
test('should handle para 1', () => {
|
|
1211
|
+
const code = `SetData("等级", level + 1);`
|
|
1212
|
+
const snippets = extractor.extractStrings(code);
|
|
1213
|
+
|
|
1214
|
+
// 验证提取的片段数量
|
|
1215
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1216
|
+
|
|
1217
|
+
let targetSnippet = snippets[0];
|
|
1218
|
+
// 函数参数需要拆分, 逐个参数捕获
|
|
1219
|
+
expect(targetSnippet.originalCode).toBe(`"等级"`);
|
|
1220
|
+
expect(targetSnippet.convertedCode).toBe(`"等级"`);
|
|
1221
|
+
expect(targetSnippet.literals).toEqual([
|
|
1222
|
+
"等级"
|
|
1223
|
+
]);
|
|
1224
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1225
|
+
});
|
|
1226
|
+
|
|
1227
|
+
// 处理C#中函数调用参数中包含普通字符串的情况
|
|
1228
|
+
test('should handle para 2', () => {
|
|
1229
|
+
const code = `bbb.Func2("等级", level, level + 1, false, isMax);`
|
|
1230
|
+
const snippets = extractor.extractStrings(code);
|
|
1231
|
+
|
|
1232
|
+
// 验证提取的片段数量
|
|
1233
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1234
|
+
|
|
1235
|
+
let targetSnippet = snippets[0];
|
|
1236
|
+
expect(targetSnippet.originalCode).toBe(`"等级"`);
|
|
1237
|
+
expect(targetSnippet.convertedCode).toBe(`"等级"`);
|
|
1238
|
+
expect(targetSnippet.literals).toEqual([
|
|
1239
|
+
"等级"
|
|
1240
|
+
]);
|
|
1241
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1242
|
+
});
|
|
1243
|
+
|
|
1244
|
+
// 处理C#中switch语句中包含普通字符串的情况
|
|
1245
|
+
test('should handle switch 1', () => {
|
|
1246
|
+
const code = `
|
|
1247
|
+
switch(condition){
|
|
1248
|
+
default:
|
|
1249
|
+
Log.Warning("实时更新自:" + rankData.Type);
|
|
1250
|
+
break;
|
|
1251
|
+
}`
|
|
1252
|
+
const snippets = extractor.extractStrings(code);
|
|
1253
|
+
|
|
1254
|
+
// 验证提取的片段数量
|
|
1255
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1256
|
+
|
|
1257
|
+
let targetSnippet = snippets[0];
|
|
1258
|
+
expect(targetSnippet.originalCode).toBe(`"实时更新自:" + rankData.Type`);
|
|
1259
|
+
// 普通函数参数不需要追加 `.TR()`, 除非包含由 `+` 符号连接字符串等的情况
|
|
1260
|
+
expect(targetSnippet.convertedCode).toBe(`"实时更新自:" + rankData.Type`);
|
|
1261
|
+
expect(targetSnippet.literals).toEqual([
|
|
1262
|
+
"实时更新自:"
|
|
1263
|
+
]);
|
|
1264
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1265
|
+
});
|
|
1266
|
+
|
|
1267
|
+
// 处理C#中switch语句中包含普通字符串的情况
|
|
1268
|
+
test('should handle switch 2', () => {
|
|
1269
|
+
const code = `
|
|
1270
|
+
switch(kwjkwlje){
|
|
1271
|
+
case (int)RANK_TYPE.天梯段位:
|
|
1272
|
+
Debug.Log1("jkwhfehwfjkh:" + rank2Data.T4zype);
|
|
1273
|
+
break;
|
|
1274
|
+
}`
|
|
1275
|
+
const snippets = extractor.extractStrings(code);
|
|
1276
|
+
|
|
1277
|
+
// 验证提取的片段数量, switch 语句中包含普通字符串的情况
|
|
1278
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1279
|
+
|
|
1280
|
+
let targetSnippet = snippets[0];
|
|
1281
|
+
expect(targetSnippet.originalCode).toBe(`"jkwhfehwfjkh:" + rank2Data.T4zype`);
|
|
1282
|
+
expect(targetSnippet.convertedCode).toBe(`"jkwhfehwfjkh:" + rank2Data.T4zype`);
|
|
1283
|
+
expect(targetSnippet.literals).toEqual([
|
|
1284
|
+
"jkwhfehwfjkh:"
|
|
1285
|
+
]);
|
|
1286
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
// 处理C#中switch语句中包含普通字符串的情况
|
|
1290
|
+
test('should handle switch 3', () => {
|
|
1291
|
+
const code = `
|
|
1292
|
+
switch(lkw){
|
|
1293
|
+
case V434:
|
|
1294
|
+
{
|
|
1295
|
+
Action2("wegwfw:" + varnws);
|
|
1296
|
+
break;
|
|
1297
|
+
}
|
|
1298
|
+
}`
|
|
1299
|
+
const snippets = extractor.extractStrings(code);
|
|
1300
|
+
|
|
1301
|
+
// 验证提取的片段数量
|
|
1302
|
+
expect(snippets.length).toBeGreaterThan(0);
|
|
1303
|
+
|
|
1304
|
+
let targetSnippet = snippets[0];
|
|
1305
|
+
expect(targetSnippet.originalCode).toBe(`"wegwfw:" + varnws`);
|
|
1306
|
+
expect(targetSnippet.convertedCode).toBe(`"wegwfw:" + varnws`);
|
|
1307
|
+
expect(targetSnippet.literals).toEqual([
|
|
1308
|
+
"wegwfw:"
|
|
1309
|
+
]);
|
|
1310
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1190
1311
|
});
|
|
1191
1312
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
const code = `
|
|
1313
|
+
// 处理C#中switch语句中包含普通字符串的情况
|
|
1314
|
+
test('should handle switch 4', () => {
|
|
1315
|
+
const code = `
|
|
1316
|
+
case V434:
|
|
1317
|
+
Action2("wegwfw:" + varnws);
|
|
1318
|
+
break;`
|
|
1195
1319
|
const snippets = extractor.extractStrings(code);
|
|
1196
1320
|
|
|
1197
1321
|
// 验证提取的片段数量
|
|
1198
1322
|
expect(snippets.length).toBeGreaterThan(0);
|
|
1199
1323
|
|
|
1200
1324
|
let targetSnippet = snippets[0];
|
|
1201
|
-
|
|
1202
|
-
expect(targetSnippet.
|
|
1203
|
-
expect(targetSnippet.convertedCode).toBe(`"等级"`);
|
|
1325
|
+
expect(targetSnippet.originalCode).toBe(`"wegwfw:" + varnws`);
|
|
1326
|
+
expect(targetSnippet.convertedCode).toBe(`"wegwfw:" + varnws`);
|
|
1204
1327
|
expect(targetSnippet.literals).toEqual([
|
|
1205
|
-
"
|
|
1328
|
+
"wegwfw:"
|
|
1206
1329
|
]);
|
|
1207
1330
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1208
|
-
})
|
|
1209
|
-
|
|
1210
|
-
|
|
1331
|
+
});
|
|
1332
|
+
|
|
1333
|
+
// 处理 C#内容中存在多个相同的包含字符串的语句时, 要每个都提取出来
|
|
1334
|
+
test('should handle lost 1', () => {
|
|
1335
|
+
const code = readFileSync('./test/KeeperDialog.cs', 'utf8');
|
|
1211
1336
|
const snippets = extractor.extractStrings(code);
|
|
1212
1337
|
|
|
1338
|
+
let targetSnippet = snippets[3];
|
|
1339
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"已购买";
|
|
1340
|
+
m_btn_buy.enabled = false;
|
|
1341
|
+
|
|
1342
|
+
//购买后自动启用`));
|
|
1343
|
+
expect(targetSnippet.originalCode).toBe(`"已购买"`);
|
|
1344
|
+
expect(targetSnippet.convertedCode).toBe(`"已购买".TR()`);
|
|
1345
|
+
expect(targetSnippet.literals).toEqual([
|
|
1346
|
+
"已购买"
|
|
1347
|
+
]);
|
|
1348
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1349
|
+
|
|
1213
1350
|
// 验证提取的片段数量
|
|
1214
|
-
expect(snippets.length).
|
|
1351
|
+
expect(snippets.length).toBeGreaterThanOrEqual(5)
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
// 字符串中包含 `)` 符号时, 也需要捕获该字符串
|
|
1355
|
+
test('should handle lost 2', () => {
|
|
1356
|
+
const code = `m_text_runeSlot.text = Tr.Format(")", _sutraCardData.Card.RuneOpenCount);`;
|
|
1357
|
+
const snippets = extractor.extractStrings(code);
|
|
1215
1358
|
|
|
1216
1359
|
let targetSnippet = snippets[0];
|
|
1217
|
-
expect(targetSnippet.
|
|
1218
|
-
expect(targetSnippet.
|
|
1360
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format(")", _sutraCardData.Card.RuneOpenCount)`));
|
|
1361
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format(")", _sutraCardData.Card.RuneOpenCount)`);
|
|
1362
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format(")", _sutraCardData.Card.RuneOpenCount)`);
|
|
1363
|
+
// 字符串中包含 `)` 符号时, 也需要捕获该字符串
|
|
1219
1364
|
expect(targetSnippet.literals).toEqual([
|
|
1220
|
-
|
|
1365
|
+
')'
|
|
1221
1366
|
]);
|
|
1222
1367
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1223
|
-
|
|
1368
|
+
|
|
1369
|
+
});
|
|
1370
|
+
|
|
1371
|
+
// 处理 C#内容时, 需要匹配出包含 `(` 符号的字符串表达式
|
|
1372
|
+
test('should handle lost 3', () => {
|
|
1373
|
+
const code = `m_text_runeSlot.text = ")";`;
|
|
1374
|
+
const snippets = extractor.extractStrings(code);
|
|
1375
|
+
|
|
1376
|
+
let targetSnippet = snippets[0];
|
|
1377
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`")"`));
|
|
1378
|
+
expect(targetSnippet.originalCode).toBe(`")"`);
|
|
1379
|
+
expect(targetSnippet.convertedCode).toBe(`")".TR()`);
|
|
1380
|
+
expect(targetSnippet.literals).toEqual([
|
|
1381
|
+
')'
|
|
1382
|
+
]);
|
|
1383
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1384
|
+
|
|
1224
1385
|
});
|
|
1225
1386
|
|
|
1226
|
-
|
|
1227
|
-
|
|
1387
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1388
|
+
test('should handle return statement 1', () => {
|
|
1228
1389
|
const code = `return "参数错误";`;
|
|
1229
1390
|
const snippets = extractor.extractStrings(code);
|
|
1230
1391
|
|
|
@@ -1237,8 +1398,10 @@ namespace TestNamespace{
|
|
|
1237
1398
|
]);
|
|
1238
1399
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1239
1400
|
|
|
1240
|
-
})
|
|
1241
|
-
|
|
1401
|
+
});
|
|
1402
|
+
|
|
1403
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1404
|
+
test('should handle return statement 2', () => {
|
|
1242
1405
|
const code = `return "";`;
|
|
1243
1406
|
const snippets = extractor.extractStrings(code);
|
|
1244
1407
|
|
|
@@ -1251,8 +1414,10 @@ namespace TestNamespace{
|
|
|
1251
1414
|
]);
|
|
1252
1415
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1253
1416
|
|
|
1254
|
-
})
|
|
1255
|
-
|
|
1417
|
+
});
|
|
1418
|
+
|
|
1419
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1420
|
+
test('should handle return statement 3', () => {
|
|
1256
1421
|
const code = `return $"";`;
|
|
1257
1422
|
const snippets = extractor.extractStrings(code);
|
|
1258
1423
|
|
|
@@ -1265,8 +1430,10 @@ namespace TestNamespace{
|
|
|
1265
1430
|
]);
|
|
1266
1431
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1267
1432
|
|
|
1268
|
-
})
|
|
1269
|
-
|
|
1433
|
+
});
|
|
1434
|
+
|
|
1435
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1436
|
+
test('should handle return statement 4', () => {
|
|
1270
1437
|
const code = `return $"fwefwe";`;
|
|
1271
1438
|
const snippets = extractor.extractStrings(code);
|
|
1272
1439
|
|
|
@@ -1279,481 +1446,256 @@ namespace TestNamespace{
|
|
|
1279
1446
|
]);
|
|
1280
1447
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1281
1448
|
|
|
1282
|
-
})
|
|
1283
|
-
test('should handle return statement 5', () => {
|
|
1284
|
-
const code = `return $"wefwf{fwef}";`;
|
|
1285
|
-
const snippets = extractor.extractStrings(code);
|
|
1286
|
-
|
|
1287
|
-
let targetSnippet = snippets[0];
|
|
1288
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"wefwf{fwef}"`));
|
|
1289
|
-
expect(targetSnippet.originalCode).toBe(`$"wefwf{fwef}"`);
|
|
1290
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("wefwf{0}", fwef)`);
|
|
1291
|
-
expect(targetSnippet.literals).toEqual([
|
|
1292
|
-
'wefwf{0}'
|
|
1293
|
-
]);
|
|
1294
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
1295
|
-
|
|
1296
|
-
})
|
|
1297
|
-
});
|
|
1298
|
-
|
|
1299
|
-
describe('should handle special characters in string', () => {
|
|
1300
|
-
test('should handle special characters in string 8', () => {
|
|
1301
|
-
const code = `
|
|
1302
|
-
m_btn_paid.text = $"<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{paidConfig.Quantity}";
|
|
1303
|
-
`;
|
|
1304
|
-
const snippets = extractor.extractStrings(code);
|
|
1305
|
-
{
|
|
1306
|
-
let targetSnippet = snippets[0];
|
|
1307
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{paidConfig.Quantity}"`));
|
|
1308
|
-
expect(targetSnippet.originalCode).toBe(`$"<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{paidConfig.Quantity}"`);
|
|
1309
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{0}", paidConfig.Quantity)`);
|
|
1310
|
-
expect(targetSnippet.literals).toEqual([
|
|
1311
|
-
`<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{0}`
|
|
1312
|
-
]);
|
|
1313
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
1314
|
-
}
|
|
1315
|
-
expect(snippets.length).toBe(1);
|
|
1316
|
-
})
|
|
1317
|
-
test('should handle special characters in string 9', () => {
|
|
1318
|
-
const code = `
|
|
1319
|
-
(GetChild($"m_textAnime{GetNextNumber()}") as TurtleTextAnimeComp)?.SetText(word);
|
|
1320
|
-
`;
|
|
1321
|
-
const snippets = extractor.extractStrings(code);
|
|
1322
|
-
{
|
|
1323
|
-
let targetSnippet = snippets[0];
|
|
1324
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"m_textAnime{GetNextNumber()}"`));
|
|
1325
|
-
expect(targetSnippet.originalCode).toBe(`$"m_textAnime{GetNextNumber()}"`);
|
|
1326
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("m_textAnime{0}", GetNextNumber())`);
|
|
1327
|
-
expect(targetSnippet.literals).toEqual([
|
|
1328
|
-
`m_textAnime{0}`
|
|
1329
|
-
]);
|
|
1330
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
1331
|
-
}
|
|
1332
|
-
expect(snippets.length).toBe(1);
|
|
1333
|
-
})
|
|
1334
|
-
test('should handle special characters in string 10', () => {
|
|
1335
|
-
const code = `
|
|
1336
|
-
(GetChild($"m_textAnime{GetNextNumber()}") as TurtleTextAnimeComp)?.SetText(word);
|
|
1337
|
-
`;
|
|
1338
|
-
const snippets = extractor.extractStrings(code);
|
|
1339
|
-
{
|
|
1340
|
-
let targetSnippet = snippets[0];
|
|
1341
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"m_textAnime{GetNextNumber()}"`));
|
|
1342
|
-
expect(targetSnippet.originalCode).toBe(`$"m_textAnime{GetNextNumber()}"`);
|
|
1343
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("m_textAnime{0}", GetNextNumber())`);
|
|
1344
|
-
expect(targetSnippet.literals).toEqual([
|
|
1345
|
-
`m_textAnime{0}`
|
|
1346
|
-
]);
|
|
1347
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
1348
|
-
}
|
|
1349
|
-
expect(snippets.length).toBe(1);
|
|
1350
|
-
})
|
|
1351
1449
|
});
|
|
1352
1450
|
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
const code = `return "
|
|
1451
|
+
// 测试处理C# `return` 语句中的字符串表达式, 提取的字符串表达式中不需要包含 `return` 关键字, 只需要包含字符串表达式
|
|
1452
|
+
test('should handle return statement 5', () => {
|
|
1453
|
+
const code = `return $"wefwf{fwef}";`;
|
|
1356
1454
|
const snippets = extractor.extractStrings(code);
|
|
1357
1455
|
|
|
1358
|
-
let targetSnippet = snippets[0];
|
|
1359
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
1360
|
-
expect(targetSnippet.originalCode).toBe(
|
|
1361
|
-
expect(targetSnippet.convertedCode).toBe(`"
|
|
1362
|
-
expect(targetSnippet.literals).toEqual([
|
|
1363
|
-
'
|
|
1364
|
-
]);
|
|
1365
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1373
|
-
expect(targetSnippet.originalCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1374
|
-
expect(targetSnippet.convertedCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1375
|
-
expect(targetSnippet.literals).toEqual([
|
|
1376
|
-
'1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1377
|
-
]);
|
|
1378
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1379
|
-
}
|
|
1380
|
-
{
|
|
1381
|
-
let targetSnippet = snippets[4];
|
|
1382
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1383
|
-
expect(targetSnippet.originalCode).toBe(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1384
|
-
expect(targetSnippet.convertedCode).toBe(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1385
|
-
expect(targetSnippet.literals).toEqual([
|
|
1386
|
-
'2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1387
|
-
]);
|
|
1388
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1389
|
-
}
|
|
1390
|
-
{
|
|
1391
|
-
let targetSnippet = snippets[6];
|
|
1392
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1393
|
-
expect(targetSnippet.originalCode).toBe(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1394
|
-
expect(targetSnippet.convertedCode).toBe(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1395
|
-
expect(targetSnippet.literals).toEqual([
|
|
1396
|
-
'4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1397
|
-
]);
|
|
1398
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1399
|
-
}
|
|
1400
|
-
})
|
|
1401
|
-
test('should handle special characters in string expression 3.1', () => {
|
|
1402
|
-
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1403
|
-
const snippets = extractor.extractStrings(code);
|
|
1404
|
-
{
|
|
1405
|
-
let targetSnippet = snippets[3];
|
|
1406
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1407
|
-
expect(targetSnippet.originalCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1408
|
-
expect(targetSnippet.convertedCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1409
|
-
expect(targetSnippet.literals).toEqual([
|
|
1410
|
-
'1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1411
|
-
]);
|
|
1412
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1413
|
-
}
|
|
1414
|
-
})
|
|
1415
|
-
test('should handle special characters in string expression 3.2', () => {
|
|
1416
|
-
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1417
|
-
const snippets = extractor.extractStrings(code);
|
|
1418
|
-
{
|
|
1419
|
-
let targetSnippet = snippets[8];
|
|
1420
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1421
|
-
expect(targetSnippet.originalCode).toBe(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1422
|
-
expect(targetSnippet.convertedCode).toBe(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1423
|
-
expect(targetSnippet.literals).toEqual([
|
|
1424
|
-
'6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1425
|
-
]);
|
|
1426
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1427
|
-
}
|
|
1428
|
-
{
|
|
1429
|
-
let targetSnippet = snippets[9];
|
|
1430
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1431
|
-
expect(targetSnippet.originalCode).toBe(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1432
|
-
expect(targetSnippet.convertedCode).toBe(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1433
|
-
expect(targetSnippet.literals).toEqual([
|
|
1434
|
-
'7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1435
|
-
]);
|
|
1436
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1437
|
-
}
|
|
1438
|
-
})
|
|
1439
|
-
test('should handle special characters in string expression 4', () => {
|
|
1440
|
-
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1441
|
-
const snippets = extractor.extractStrings(code);
|
|
1442
|
-
{
|
|
1443
|
-
let targetSnippet = snippets[5];
|
|
1444
|
-
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1445
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"3. {wef}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1446
|
-
expect(targetSnippet.originalCode).toBe(`$"3. {wef}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1447
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("3. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wef)`);
|
|
1448
|
-
expect(targetSnippet.literals).toEqual([
|
|
1449
|
-
'3. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1450
|
-
]);
|
|
1451
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
1452
|
-
}
|
|
1453
|
-
})
|
|
1454
|
-
test('should handle special characters in string expression 5', () => {
|
|
1455
|
-
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1456
|
-
const snippets = extractor.extractStrings(code);
|
|
1457
|
-
{
|
|
1458
|
-
let targetSnippet = snippets[10];
|
|
1459
|
-
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1460
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"8. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1461
|
-
expect(targetSnippet.originalCode).toBe(`$"8. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1462
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("8. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1463
|
-
expect(targetSnippet.literals).toEqual([
|
|
1464
|
-
'8. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1465
|
-
]);
|
|
1466
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
1467
|
-
}
|
|
1468
|
-
})
|
|
1469
|
-
test('should handle special characters in string expression 6', () => {
|
|
1470
|
-
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1471
|
-
const snippets = extractor.extractStrings(code);
|
|
1472
|
-
{
|
|
1473
|
-
let targetSnippet = snippets[11];
|
|
1474
|
-
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1475
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"9. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1476
|
-
expect(targetSnippet.originalCode).toBe(`$"9. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1477
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("9. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1478
|
-
expect(targetSnippet.literals).toEqual([
|
|
1479
|
-
'9. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1480
|
-
]);
|
|
1481
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
1482
|
-
}
|
|
1483
|
-
})
|
|
1484
|
-
test('should handle special characters in string expression 7', () => {
|
|
1485
|
-
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1456
|
+
let targetSnippet = snippets[0];
|
|
1457
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"wefwf{fwef}"`));
|
|
1458
|
+
expect(targetSnippet.originalCode).toBe(`$"wefwf{fwef}"`);
|
|
1459
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("wefwf{0}", fwef)`);
|
|
1460
|
+
expect(targetSnippet.literals).toEqual([
|
|
1461
|
+
'wefwf{0}'
|
|
1462
|
+
]);
|
|
1463
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1464
|
+
|
|
1465
|
+
});
|
|
1466
|
+
|
|
1467
|
+
// 测试处理C#字符串表达式中包含各种特殊字符的情况
|
|
1468
|
+
test('should handle special characters in string expression 1', () => {
|
|
1469
|
+
const code = `return "abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\";`;
|
|
1486
1470
|
const snippets = extractor.extractStrings(code);
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
]);
|
|
1497
|
-
expect(targetSnippet.isChanged).toBe(true);
|
|
1498
|
-
}
|
|
1499
|
-
})
|
|
1471
|
+
|
|
1472
|
+
let targetSnippet = snippets[0];
|
|
1473
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\"`));
|
|
1474
|
+
expect(targetSnippet.originalCode).toBe(`"abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\"`);
|
|
1475
|
+
expect(targetSnippet.convertedCode).toBe(`"abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\"`);
|
|
1476
|
+
expect(targetSnippet.literals).toEqual([
|
|
1477
|
+
'abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+{}|:\\"<>?1234567890\\\\'
|
|
1478
|
+
]);
|
|
1479
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1500
1480
|
});
|
|
1501
1481
|
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
const code =
|
|
1505
|
-
(GetChild($"vwvwe{index + 1}") as LargeLotterySpellCardComp)?.InitData(spellCardId, true);
|
|
1506
|
-
`;
|
|
1482
|
+
// 测试处理在C#类成员初始赋值语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1483
|
+
test('should handle member initial assignment', () => {
|
|
1484
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1507
1485
|
const snippets = extractor.extractStrings(code);
|
|
1508
1486
|
{
|
|
1509
1487
|
let targetSnippet = snippets[0];
|
|
1510
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
1511
|
-
expect(targetSnippet.originalCode).toBe(
|
|
1512
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1488
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"\\\\"`));
|
|
1489
|
+
expect(targetSnippet.originalCode).toBe(`"\\\\"`);
|
|
1490
|
+
expect(targetSnippet.convertedCode).toBe(`"\\\\"`);
|
|
1513
1491
|
expect(targetSnippet.literals).toEqual([
|
|
1514
|
-
|
|
1492
|
+
'\\\\'
|
|
1515
1493
|
]);
|
|
1516
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1494
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1517
1495
|
}
|
|
1518
|
-
expect(snippets.length).toBe(1);
|
|
1519
|
-
})
|
|
1520
|
-
test('should handle string expression capture range 2', () => {
|
|
1521
|
-
const code = `
|
|
1522
|
-
(GetChild($"brrr_{index + 1}") as LargeLotterySpellCardComp)?.InitData(spellCardId, true);
|
|
1523
|
-
`;
|
|
1524
|
-
const snippets = extractor.extractStrings(code);
|
|
1525
1496
|
{
|
|
1526
|
-
let targetSnippet = snippets[
|
|
1527
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
1528
|
-
expect(targetSnippet.originalCode).toBe(
|
|
1529
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1497
|
+
let targetSnippet = snippets[1];
|
|
1498
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"\\n"`));
|
|
1499
|
+
expect(targetSnippet.originalCode).toBe(`"\\n"`);
|
|
1500
|
+
expect(targetSnippet.convertedCode).toBe(`"\\n"`);
|
|
1530
1501
|
expect(targetSnippet.literals).toEqual([
|
|
1531
|
-
|
|
1502
|
+
'\\n'
|
|
1532
1503
|
]);
|
|
1533
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1504
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1534
1505
|
}
|
|
1535
|
-
expect(snippets.length).toBe(1);
|
|
1536
|
-
})
|
|
1537
|
-
test('should handle string expression capture range 3', () => {
|
|
1538
|
-
const code = `
|
|
1539
|
-
(GetChild($"m_card_{index}") as LargeLotterySpellCardComp)?.PlayEff();
|
|
1540
|
-
`;
|
|
1541
|
-
const snippets = extractor.extractStrings(code);
|
|
1542
1506
|
{
|
|
1543
|
-
let targetSnippet = snippets[
|
|
1544
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"
|
|
1545
|
-
expect(targetSnippet.originalCode).toBe(`$"
|
|
1546
|
-
expect(targetSnippet.convertedCode).toBe(
|
|
1507
|
+
let targetSnippet = snippets[2];
|
|
1508
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"\\t"`));
|
|
1509
|
+
expect(targetSnippet.originalCode).toBe(`$"\\t"`);
|
|
1510
|
+
expect(targetSnippet.convertedCode).toBe(`$"\\t"`);
|
|
1547
1511
|
expect(targetSnippet.literals).toEqual([
|
|
1548
|
-
|
|
1512
|
+
'\\t'
|
|
1549
1513
|
]);
|
|
1550
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1514
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1551
1515
|
}
|
|
1552
|
-
expect(snippets.length).toBe(1);
|
|
1553
|
-
})
|
|
1554
1516
|
});
|
|
1555
1517
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
const code =
|
|
1559
|
-
namespace FaBao.UI.Comp
|
|
1560
|
-
{
|
|
1561
|
-
public partial class ItemCommonComp
|
|
1562
|
-
{
|
|
1563
|
-
public void BindData(bool needCompare = false)
|
|
1564
|
-
{
|
|
1565
|
-
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
`;
|
|
1518
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1519
|
+
test('should handle special characters in string expression 3', () => {
|
|
1520
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1570
1521
|
const snippets = extractor.extractStrings(code);
|
|
1571
1522
|
{
|
|
1572
|
-
let targetSnippet = snippets[
|
|
1573
|
-
|
|
1574
|
-
expect(targetSnippet.
|
|
1575
|
-
expect(targetSnippet.
|
|
1576
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
1523
|
+
let targetSnippet = snippets[3];
|
|
1524
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1525
|
+
expect(targetSnippet.originalCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1526
|
+
expect(targetSnippet.convertedCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1577
1527
|
expect(targetSnippet.literals).toEqual([
|
|
1578
|
-
'{
|
|
1528
|
+
'1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1579
1529
|
]);
|
|
1580
1530
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1581
1531
|
}
|
|
1582
|
-
expect(snippets.length).toBe(1);
|
|
1583
|
-
})
|
|
1584
|
-
test('should handle string expression in method call parameter 2', () => {
|
|
1585
|
-
const code = `
|
|
1586
|
-
namespace FaBao.UI.Comp
|
|
1587
|
-
{
|
|
1588
|
-
public partial class ItemCommonComp
|
|
1589
|
-
{
|
|
1590
|
-
public void BindData(bool needCompare = false, long needCompare2 = 23, float needCompare2 = 324.0)
|
|
1591
|
-
{
|
|
1592
|
-
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
`;
|
|
1597
|
-
const snippets = extractor.extractStrings(code);
|
|
1598
1532
|
{
|
|
1599
|
-
let targetSnippet = snippets[
|
|
1600
|
-
|
|
1601
|
-
expect(targetSnippet.
|
|
1602
|
-
expect(targetSnippet.
|
|
1603
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
1533
|
+
let targetSnippet = snippets[4];
|
|
1534
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1535
|
+
expect(targetSnippet.originalCode).toBe(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1536
|
+
expect(targetSnippet.convertedCode).toBe(`"2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1604
1537
|
expect(targetSnippet.literals).toEqual([
|
|
1605
|
-
'{
|
|
1538
|
+
'2. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1606
1539
|
]);
|
|
1607
1540
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1608
1541
|
}
|
|
1609
|
-
expect(snippets.length).toBe(1);
|
|
1610
|
-
})
|
|
1611
|
-
test('should handle string expression in method call parameter 3', () => {
|
|
1612
|
-
const code = `
|
|
1613
|
-
namespace FaBao.UI.Comp
|
|
1614
|
-
{
|
|
1615
|
-
public partial class ItemCommonComp
|
|
1616
|
-
{
|
|
1617
|
-
public void BindData(string wkle, bool needCompare = false, int needCompare2 = false)
|
|
1618
|
-
{
|
|
1619
|
-
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
`;
|
|
1624
|
-
const snippets = extractor.extractStrings(code);
|
|
1625
1542
|
{
|
|
1626
|
-
let targetSnippet = snippets[
|
|
1627
|
-
|
|
1628
|
-
expect(targetSnippet.
|
|
1629
|
-
expect(targetSnippet.
|
|
1630
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
1543
|
+
let targetSnippet = snippets[6];
|
|
1544
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1545
|
+
expect(targetSnippet.originalCode).toBe(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1546
|
+
expect(targetSnippet.convertedCode).toBe(`"4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1631
1547
|
expect(targetSnippet.literals).toEqual([
|
|
1632
|
-
'{
|
|
1548
|
+
'4. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1633
1549
|
]);
|
|
1634
1550
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1635
1551
|
}
|
|
1636
|
-
|
|
1637
|
-
})
|
|
1638
|
-
test('should handle string expression in method call parameter 4', () => {
|
|
1639
|
-
const code = `
|
|
1640
|
-
namespace FaBao.UI.Comp
|
|
1641
|
-
{
|
|
1642
|
-
public partial class ItemCommonComp
|
|
1643
|
-
{
|
|
1644
|
-
public void BindData(string wkle = "11111", bool needCompare = false, int needCompare2 = false)
|
|
1645
|
-
{
|
|
1646
|
-
}
|
|
1647
|
-
|
|
1648
|
-
public void BindData(string wkle = "22", string wkle = "werwer", bool needCompare = false, string wkle = "wefwewef31f", int needCompare2 = false, string wkle = "df223")
|
|
1649
|
-
{
|
|
1650
|
-
}
|
|
1552
|
+
});
|
|
1651
1553
|
|
|
1652
|
-
|
|
1554
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1555
|
+
test('should handle special characters in string expression 3.1', () => {
|
|
1556
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1557
|
+
const snippets = extractor.extractStrings(code);
|
|
1653
1558
|
{
|
|
1559
|
+
let targetSnippet = snippets[3];
|
|
1560
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1561
|
+
expect(targetSnippet.originalCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1562
|
+
expect(targetSnippet.convertedCode).toBe(`"1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1563
|
+
expect(targetSnippet.literals).toEqual([
|
|
1564
|
+
'1. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1565
|
+
]);
|
|
1566
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1654
1567
|
}
|
|
1568
|
+
});
|
|
1655
1569
|
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
`;
|
|
1570
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1571
|
+
test('should handle special characters in string expression of return sentence', () => {
|
|
1572
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1663
1573
|
const snippets = extractor.extractStrings(code);
|
|
1664
1574
|
{
|
|
1665
|
-
let targetSnippet = snippets[
|
|
1666
|
-
//
|
|
1667
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"
|
|
1668
|
-
expect(targetSnippet.originalCode).toBe(`"
|
|
1669
|
-
expect(targetSnippet.convertedCode).toBe(`"
|
|
1575
|
+
let targetSnippet = snippets[7];
|
|
1576
|
+
// 需要统一匹配 `return` 语句中的字符串表达式
|
|
1577
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1578
|
+
expect(targetSnippet.originalCode).toBe(`"5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1579
|
+
expect(targetSnippet.convertedCode).toBe(`"5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1670
1580
|
expect(targetSnippet.literals).toEqual([
|
|
1671
|
-
'
|
|
1581
|
+
'5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1672
1582
|
]);
|
|
1673
1583
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1674
1584
|
}
|
|
1585
|
+
});
|
|
1586
|
+
|
|
1587
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1588
|
+
test('should handle special characters in string expression 3.2', () => {
|
|
1589
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1590
|
+
const snippets = extractor.extractStrings(code);
|
|
1675
1591
|
{
|
|
1676
|
-
let targetSnippet = snippets[
|
|
1677
|
-
|
|
1678
|
-
expect(targetSnippet.
|
|
1679
|
-
expect(targetSnippet.
|
|
1680
|
-
expect(targetSnippet.convertedCode).toBe(`"22"`);
|
|
1592
|
+
let targetSnippet = snippets[8];
|
|
1593
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1594
|
+
expect(targetSnippet.originalCode).toBe(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1595
|
+
expect(targetSnippet.convertedCode).toBe(`"6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1681
1596
|
expect(targetSnippet.literals).toEqual([
|
|
1682
|
-
'
|
|
1597
|
+
'6. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1683
1598
|
]);
|
|
1684
1599
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1685
1600
|
}
|
|
1686
1601
|
{
|
|
1687
|
-
let targetSnippet = snippets[
|
|
1688
|
-
|
|
1689
|
-
expect(targetSnippet.
|
|
1690
|
-
expect(targetSnippet.
|
|
1691
|
-
expect(targetSnippet.convertedCode).toBe(`"werwer"`);
|
|
1602
|
+
let targetSnippet = snippets[9];
|
|
1603
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1604
|
+
expect(targetSnippet.originalCode).toBe(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1605
|
+
expect(targetSnippet.convertedCode).toBe(`"7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1692
1606
|
expect(targetSnippet.literals).toEqual([
|
|
1693
|
-
'
|
|
1607
|
+
'7. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1694
1608
|
]);
|
|
1695
1609
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1696
1610
|
}
|
|
1611
|
+
});
|
|
1612
|
+
|
|
1613
|
+
// 测试处理在C#各种语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#字符串边界识别和捕获
|
|
1614
|
+
test('should handle special characters in string expression 4', () => {
|
|
1615
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1616
|
+
const snippets = extractor.extractStrings(code);
|
|
1697
1617
|
{
|
|
1698
|
-
let targetSnippet = snippets[
|
|
1699
|
-
//
|
|
1700
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
1701
|
-
expect(targetSnippet.originalCode).toBe(
|
|
1702
|
-
expect(targetSnippet.convertedCode).toBe(`"
|
|
1618
|
+
let targetSnippet = snippets[5];
|
|
1619
|
+
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1620
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"3. {wef}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1621
|
+
expect(targetSnippet.originalCode).toBe(`$"3. {wef}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1622
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("3. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wef)`);
|
|
1703
1623
|
expect(targetSnippet.literals).toEqual([
|
|
1704
|
-
'
|
|
1624
|
+
'3. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1705
1625
|
]);
|
|
1706
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1626
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1707
1627
|
}
|
|
1628
|
+
});
|
|
1629
|
+
|
|
1630
|
+
// 测试处理在C#各种形式语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#内插字符串边界识别和捕获
|
|
1631
|
+
test('should handle special characters in string expression 5', () => {
|
|
1632
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1633
|
+
const snippets = extractor.extractStrings(code);
|
|
1708
1634
|
{
|
|
1709
|
-
let targetSnippet = snippets[
|
|
1710
|
-
//
|
|
1711
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
1712
|
-
expect(targetSnippet.originalCode).toBe(
|
|
1713
|
-
expect(targetSnippet.convertedCode).toBe(`"
|
|
1635
|
+
let targetSnippet = snippets[10];
|
|
1636
|
+
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1637
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"8. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1638
|
+
expect(targetSnippet.originalCode).toBe(`$"8. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1639
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("8. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1714
1640
|
expect(targetSnippet.literals).toEqual([
|
|
1715
|
-
'
|
|
1641
|
+
'8. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1716
1642
|
]);
|
|
1717
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1643
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1718
1644
|
}
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
// 测试处理在C#各种形式语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#内插字符串边界识别和捕获
|
|
1648
|
+
test('should handle special characters in string expression 6', () => {
|
|
1649
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1650
|
+
const snippets = extractor.extractStrings(code);
|
|
1719
1651
|
{
|
|
1720
|
-
let targetSnippet = snippets[
|
|
1721
|
-
//
|
|
1722
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
1723
|
-
expect(targetSnippet.originalCode).toBe(
|
|
1724
|
-
expect(targetSnippet.convertedCode).toBe(`"(
|
|
1652
|
+
let targetSnippet = snippets[11];
|
|
1653
|
+
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1654
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"9. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1655
|
+
expect(targetSnippet.originalCode).toBe(`$"9. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1656
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("9. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1725
1657
|
expect(targetSnippet.literals).toEqual([
|
|
1726
|
-
'(
|
|
1658
|
+
'9. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1727
1659
|
]);
|
|
1728
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1660
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1729
1661
|
}
|
|
1662
|
+
});
|
|
1663
|
+
|
|
1664
|
+
// 测试处理在C#各种形式语句中, 字符串表达式中包含各种特殊字符的情况, 工具中需要统一处理C#内插字符串边界识别和捕获
|
|
1665
|
+
test('should handle special characters in string expression 7', () => {
|
|
1666
|
+
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
1667
|
+
const snippets = extractor.extractStrings(code);
|
|
1730
1668
|
{
|
|
1731
|
-
let targetSnippet = snippets[
|
|
1732
|
-
//
|
|
1733
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
1734
|
-
expect(targetSnippet.originalCode).toBe(
|
|
1735
|
-
|
|
1669
|
+
let targetSnippet = snippets[12];
|
|
1670
|
+
// 需要支持内插字符串中的特殊转义字符组合: `{{` 表示 `{`, `}}` 表示 `}`, 但是 `{{`和`}}` 从内插字符串转 `Tr.Format(...)` 形式时, 不需要转为 `{`和`}`, `{xxx}` 表示内插表达式
|
|
1671
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"10. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`));
|
|
1672
|
+
expect(targetSnippet.originalCode).toBe(`$"10. {wefff}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
1673
|
+
// 需要统一匹配 `return` 语句中的字符串表达式
|
|
1674
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("10. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\", wefff)`);
|
|
1736
1675
|
expect(targetSnippet.literals).toEqual([
|
|
1737
|
-
'
|
|
1676
|
+
'10. {0}{{}}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\'
|
|
1738
1677
|
]);
|
|
1739
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1678
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1740
1679
|
}
|
|
1680
|
+
});
|
|
1681
|
+
|
|
1682
|
+
test('should handle optional value assignment', () => {
|
|
1683
|
+
const code = `m_text_otherName.text = battleModel.TeammatePlayerData?.Name ?? "";`;
|
|
1684
|
+
const snippets = extractor.extractStrings(code);
|
|
1741
1685
|
{
|
|
1742
|
-
let targetSnippet = snippets[
|
|
1743
|
-
|
|
1744
|
-
expect(targetSnippet.
|
|
1745
|
-
expect(targetSnippet.
|
|
1746
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
1686
|
+
let targetSnippet = snippets[0];
|
|
1687
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`battleModel.TeammatePlayerData?.Name ?? ""`));
|
|
1688
|
+
expect(targetSnippet.originalCode).toBe(`battleModel.TeammatePlayerData?.Name ?? ""`);
|
|
1689
|
+
expect(targetSnippet.convertedCode).toBe(`battleModel.TeammatePlayerData?.Name ?? "".TR()`);
|
|
1747
1690
|
expect(targetSnippet.literals).toEqual([
|
|
1748
|
-
'
|
|
1691
|
+
''
|
|
1749
1692
|
]);
|
|
1750
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1693
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1751
1694
|
}
|
|
1752
|
-
})
|
|
1753
1695
|
});
|
|
1754
1696
|
|
|
1755
|
-
|
|
1756
|
-
|
|
1697
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1698
|
+
test('should handle string in comment 1', () => {
|
|
1757
1699
|
const code = `
|
|
1758
1700
|
protected override void OnShow(object param)
|
|
1759
1701
|
{
|
|
@@ -1771,8 +1713,10 @@ namespace FaBao.UI.Comp
|
|
|
1771
1713
|
]);
|
|
1772
1714
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1773
1715
|
}
|
|
1774
|
-
})
|
|
1775
|
-
|
|
1716
|
+
});
|
|
1717
|
+
|
|
1718
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1719
|
+
test('should handle string in comment 2', () => {
|
|
1776
1720
|
const code = `
|
|
1777
1721
|
protected override void OnShow(object param)
|
|
1778
1722
|
{
|
|
@@ -1790,8 +1734,10 @@ namespace FaBao.UI.Comp
|
|
|
1790
1734
|
]);
|
|
1791
1735
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1792
1736
|
}
|
|
1793
|
-
})
|
|
1794
|
-
|
|
1737
|
+
});
|
|
1738
|
+
|
|
1739
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1740
|
+
test('should handle string in comment 3', () => {
|
|
1795
1741
|
const code = `
|
|
1796
1742
|
protected override void OnShow(object param)
|
|
1797
1743
|
{
|
|
@@ -1809,8 +1755,10 @@ namespace FaBao.UI.Comp
|
|
|
1809
1755
|
]);
|
|
1810
1756
|
expect(targetSnippet.isChanged).toBe(true);
|
|
1811
1757
|
}
|
|
1812
|
-
})
|
|
1813
|
-
|
|
1758
|
+
});
|
|
1759
|
+
|
|
1760
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1761
|
+
test('should handle string in comment 4', () => {
|
|
1814
1762
|
const code = `
|
|
1815
1763
|
protected override void OnShow(object param)
|
|
1816
1764
|
{
|
|
@@ -1828,8 +1776,10 @@ namespace FaBao.UI.Comp
|
|
|
1828
1776
|
]);
|
|
1829
1777
|
expect(targetSnippet.isChanged).toBe(false);
|
|
1830
1778
|
}
|
|
1831
|
-
})
|
|
1832
|
-
|
|
1779
|
+
});
|
|
1780
|
+
|
|
1781
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1782
|
+
test('should handle string in comment 5', () => {
|
|
1833
1783
|
const code = `
|
|
1834
1784
|
protected override void OnShow(object param)
|
|
1835
1785
|
{
|
|
@@ -1847,799 +1797,955 @@ namespace FaBao.UI.Comp
|
|
|
1847
1797
|
]);
|
|
1848
1798
|
expect(targetSnippet.isChanged).toBe(true);
|
|
1849
1799
|
}
|
|
1850
|
-
})
|
|
1851
|
-
|
|
1800
|
+
});
|
|
1801
|
+
|
|
1802
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1803
|
+
test('should handle complex string 1', () => {
|
|
1852
1804
|
const code = `
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
m_thumbnail_holder.url = FUISys.Instance.GetIconUrl(_curShopDetail.ShopConfig.Thumbnail);
|
|
1856
|
-
m_btn_buy.text = $"¥ {curGoodsConfig.Price}";
|
|
1857
|
-
m_text_timeleft.text = curShop.TimeLimitData.RemainTime().TR() + "后消失".TR();
|
|
1805
|
+
infoStr += $"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n";
|
|
1806
|
+
infoStr += $"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n";
|
|
1858
1807
|
`;
|
|
1859
1808
|
const snippets = extractor.extractStrings(code);
|
|
1860
1809
|
{
|
|
1861
|
-
let targetSnippet = snippets[
|
|
1862
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
1863
|
-
expect(targetSnippet.originalCode).toBe(
|
|
1864
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
1810
|
+
let targetSnippet = snippets[0];
|
|
1811
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n"`));
|
|
1812
|
+
expect(targetSnippet.originalCode).toBe(`$"伤害类型: [color={colorCode}][b]{_damageInfo.DamageType}[/b][/color]\n"`);
|
|
1813
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
1865
1814
|
expect(targetSnippet.literals).toEqual([
|
|
1866
|
-
'
|
|
1815
|
+
'伤害类型: [color={0}][b]{1}[/b][/color]\n'
|
|
1867
1816
|
]);
|
|
1868
|
-
expect(targetSnippet.isChanged).toBe(
|
|
1817
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1869
1818
|
}
|
|
1870
|
-
})
|
|
1871
1819
|
});
|
|
1872
1820
|
|
|
1873
|
-
|
|
1874
|
-
|
|
1821
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1822
|
+
test('should handle complex string 2', () => {
|
|
1875
1823
|
const code = `
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
break;
|
|
1880
|
-
}`
|
|
1824
|
+
infoStr += Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType);
|
|
1825
|
+
infoStr += $"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n";
|
|
1826
|
+
`;
|
|
1881
1827
|
const snippets = extractor.extractStrings(code);
|
|
1828
|
+
{
|
|
1829
|
+
let targetSnippet = snippets[0];
|
|
1830
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`));
|
|
1831
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
1832
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("伤害类型: [color={0}][b]{1}[/b][/color]\n", colorCode, _damageInfo.DamageType)`);
|
|
1833
|
+
expect(targetSnippet.literals).toEqual([
|
|
1834
|
+
'伤害类型: [color={0}][b]{1}[/b][/color]\n'
|
|
1835
|
+
]);
|
|
1836
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1837
|
+
}
|
|
1838
|
+
});
|
|
1882
1839
|
|
|
1883
|
-
|
|
1884
|
-
|
|
1840
|
+
// 正确处理C# 字符串表达式中递归内嵌字符串表达式的情况: 需要正确转换内插字符串格式
|
|
1841
|
+
test('should handle fix interpolated string nested literals', () => {
|
|
1842
|
+
const code = `infoStr += $"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n";`;
|
|
1843
|
+
const snippets = extractor.extractStrings(code);
|
|
1844
|
+
{
|
|
1845
|
+
let targetSnippet = snippets[0];
|
|
1846
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n"`));
|
|
1847
|
+
expect(targetSnippet.originalCode).toBe(`$"是否暴击: [b]{(_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否")}[/b]\n"`);
|
|
1848
|
+
// 需要正确转换内插字符串格式
|
|
1849
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("是否暴击: [b]{0}[/b]\n", (_damageInfo.IsCritical ? "[color=#00B000]是[/color]" : "否"))`);
|
|
1850
|
+
expect(targetSnippet.literals).toEqual([
|
|
1851
|
+
'是否暴击: [b]{0}[/b]\n'
|
|
1852
|
+
]);
|
|
1853
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1854
|
+
}
|
|
1855
|
+
});
|
|
1885
1856
|
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
// 普通函数参数不需要追加 `.TR()`, 除非包含由 `+` 符号连接字符串等的情况
|
|
1889
|
-
expect(targetSnippet.convertedCode).toBe(`"实时更新自:" + rankData.Type`);
|
|
1890
|
-
expect(targetSnippet.literals).toEqual([
|
|
1891
|
-
"实时更新自:"
|
|
1892
|
-
]);
|
|
1893
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1894
|
-
})
|
|
1895
|
-
test('should handle switch 2', () => {
|
|
1857
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1858
|
+
test('should handle complex string with optional value 3', () => {
|
|
1896
1859
|
const code = `
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1860
|
+
else if (battleModel.CurGameType == BattleModel.GameType.Teamwork)
|
|
1861
|
+
{
|
|
1862
|
+
//合作模式显示队友名称
|
|
1863
|
+
m_text_otherName.text = battleModel.TeammatePlayerData?.Name ?? "";
|
|
1864
|
+
}
|
|
1865
|
+
`;
|
|
1902
1866
|
const snippets = extractor.extractStrings(code);
|
|
1867
|
+
{
|
|
1868
|
+
let targetSnippet = snippets[0];
|
|
1869
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`battleModel.TeammatePlayerData?.Name ?? ""`));
|
|
1870
|
+
expect(targetSnippet.originalCode).toBe(`battleModel.TeammatePlayerData?.Name ?? ""`);
|
|
1871
|
+
expect(targetSnippet.convertedCode).toBe(`battleModel.TeammatePlayerData?.Name ?? "".TR()`);
|
|
1872
|
+
expect(targetSnippet.literals).toEqual([
|
|
1873
|
+
''
|
|
1874
|
+
]);
|
|
1875
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1876
|
+
}
|
|
1877
|
+
});
|
|
1903
1878
|
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
let targetSnippet = snippets[0];
|
|
1908
|
-
expect(targetSnippet.originalCode).toBe(`"jkwhfehwfjkh:" + rank2Data.T4zype`);
|
|
1909
|
-
expect(targetSnippet.convertedCode).toBe(`"jkwhfehwfjkh:" + rank2Data.T4zype`);
|
|
1910
|
-
expect(targetSnippet.literals).toEqual([
|
|
1911
|
-
"jkwhfehwfjkh:"
|
|
1912
|
-
]);
|
|
1913
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1914
|
-
})
|
|
1915
|
-
test('should handle switch 3', () => {
|
|
1879
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1880
|
+
test('should handle complex string 4', () => {
|
|
1916
1881
|
const code = `
|
|
1917
|
-
|
|
1918
|
-
|
|
1882
|
+
private void OnBtnIaa(EventContext context)
|
|
1883
|
+
{
|
|
1884
|
+
var iaaConfig = IAAConfigTable.GetConfigById((int)IAAId.境界失败_加速冷却);
|
|
1885
|
+
if (iaaConfig == null)
|
|
1919
1886
|
{
|
|
1920
|
-
|
|
1921
|
-
break;
|
|
1887
|
+
return;
|
|
1922
1888
|
}
|
|
1923
|
-
}`
|
|
1924
|
-
const snippets = extractor.extractStrings(code);
|
|
1925
|
-
|
|
1926
|
-
// 验证提取的片段数量
|
|
1927
|
-
expect(snippets.length).toBeGreaterThan(0);
|
|
1928
1889
|
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
"wegwfw:"
|
|
1934
|
-
]);
|
|
1935
|
-
expect(targetSnippet.isChanged).toBe(false);
|
|
1936
|
-
})
|
|
1937
|
-
test('should handle switch 4', () => {
|
|
1938
|
-
const code = `
|
|
1939
|
-
case V434:
|
|
1940
|
-
Action2("wegwfw:" + varnws);
|
|
1941
|
-
break;`
|
|
1890
|
+
string des = $"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟";
|
|
1891
|
+
this.GetModel<IAAModel>().ShowAdWithDialog(IAAId.境界失败_加速冷却, "加速时间", des, null);
|
|
1892
|
+
}
|
|
1893
|
+
`;
|
|
1942
1894
|
const snippets = extractor.extractStrings(code);
|
|
1895
|
+
{
|
|
1896
|
+
let targetSnippet = snippets[0];
|
|
1897
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟"`));
|
|
1898
|
+
expect(targetSnippet.originalCode).toBe(`$"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟"`);
|
|
1899
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("观看视频后\n等待时间减少{0}分钟", iaaConfig.EffectValue / 60)`);
|
|
1900
|
+
expect(targetSnippet.literals).toEqual([
|
|
1901
|
+
'观看视频后\n等待时间减少{0}分钟'
|
|
1902
|
+
]);
|
|
1903
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1904
|
+
}
|
|
1905
|
+
});
|
|
1943
1906
|
|
|
1944
|
-
|
|
1945
|
-
|
|
1907
|
+
// 需要正确识别函数调用参数中每个参数的边界, 并识别每个参数中的字符串表达式
|
|
1908
|
+
test('should handle strings in function call arguments', () => {
|
|
1909
|
+
const code = `
|
|
1910
|
+
private void OnBtnIaa(EventContext context)
|
|
1911
|
+
{
|
|
1912
|
+
var iaaConfig = IAAConfigTable.GetConfigById((int)IAAId.境界失败_加速冷却);
|
|
1913
|
+
if (iaaConfig == null)
|
|
1914
|
+
{
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1946
1917
|
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1918
|
+
string des = $"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟";
|
|
1919
|
+
this.GetModel<IAAModel>().ShowAdWithDialog(IAAId.境界失败_加速冷却, "加速时间", des, null);
|
|
1920
|
+
}
|
|
1921
|
+
`;
|
|
1922
|
+
const snippets = extractor.extractStrings(code);
|
|
1923
|
+
{
|
|
1924
|
+
let targetSnippet = snippets[1];
|
|
1925
|
+
// 需要正确识别函数调用参数中每个参数的边界, 并识别每个参数中的字符串表达式
|
|
1926
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"加速时间"`));
|
|
1927
|
+
expect(targetSnippet.originalCode).toBe(`"加速时间"`);
|
|
1928
|
+
expect(targetSnippet.convertedCode).toBe(`"加速时间"`);
|
|
1929
|
+
expect(targetSnippet.literals).toEqual([
|
|
1930
|
+
'加速时间'
|
|
1931
|
+
]);
|
|
1932
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1933
|
+
}
|
|
1955
1934
|
});
|
|
1956
1935
|
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
const code = `
|
|
1936
|
+
// 正确处理C#注释中的字符串表达式 - 同样需要从字符串中提取字符串表达式信息
|
|
1937
|
+
test('should handle string in comment 5', () => {
|
|
1938
|
+
const code = `
|
|
1939
|
+
m_text_percent.text = $"{curGoodsConfig.RebateRate}%";
|
|
1940
|
+
m_name_holder.url = FUISys.Instance.GetIconUrl(_curShopDetail.ShopConfig.Name);
|
|
1941
|
+
m_thumbnail_holder.url = FUISys.Instance.GetIconUrl(_curShopDetail.ShopConfig.Thumbnail);
|
|
1942
|
+
m_btn_buy.text = $"¥ {curGoodsConfig.Price}";
|
|
1943
|
+
m_text_timeleft.text = curShop.TimeLimitData.RemainTime().TR() + "后消失".TR();
|
|
1944
|
+
`;
|
|
1960
1945
|
const snippets = extractor.extractStrings(code);
|
|
1961
1946
|
{
|
|
1962
|
-
let
|
|
1963
|
-
expect(
|
|
1964
|
-
expect(
|
|
1965
|
-
expect(
|
|
1966
|
-
|
|
1967
|
-
'
|
|
1947
|
+
let targetSnippet = snippets[2];
|
|
1948
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`));
|
|
1949
|
+
expect(targetSnippet.originalCode).toBe(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`);
|
|
1950
|
+
expect(targetSnippet.convertedCode).toBe(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`);
|
|
1951
|
+
expect(targetSnippet.literals).toEqual([
|
|
1952
|
+
'后消失'
|
|
1968
1953
|
]);
|
|
1954
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
1969
1955
|
}
|
|
1970
|
-
})
|
|
1971
|
-
|
|
1972
|
-
|
|
1956
|
+
});
|
|
1957
|
+
|
|
1958
|
+
// 正确处理C# `switch` 表达式形式中的字符串表达式
|
|
1959
|
+
test('should handle switch expression string', () => {
|
|
1960
|
+
const code = `
|
|
1961
|
+
case (int)State.Lock:
|
|
1962
|
+
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
1963
|
+
break;
|
|
1964
|
+
`;
|
|
1973
1965
|
const snippets = extractor.extractStrings(code);
|
|
1974
1966
|
{
|
|
1975
|
-
let
|
|
1976
|
-
expect(
|
|
1977
|
-
expect(
|
|
1978
|
-
expect(
|
|
1979
|
-
|
|
1980
|
-
'
|
|
1967
|
+
let targetSnippet = snippets[0];
|
|
1968
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`));
|
|
1969
|
+
expect(targetSnippet.originalCode).toBe(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`);
|
|
1970
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("灵田{0}级解锁", _model.GetFarmLandUnlockLevel(_landId))`);
|
|
1971
|
+
expect(targetSnippet.literals).toEqual([
|
|
1972
|
+
'灵田{0}级解锁'
|
|
1981
1973
|
]);
|
|
1974
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1982
1975
|
}
|
|
1983
|
-
})
|
|
1984
|
-
|
|
1985
|
-
|
|
1976
|
+
});
|
|
1977
|
+
|
|
1978
|
+
// 正确识别C# 行注释语句边界, 行注释不能影响上下行的字符串提取
|
|
1979
|
+
test('should handle comment boundary 1', () => {
|
|
1980
|
+
const code = `
|
|
1981
|
+
//上锁
|
|
1982
|
+
case (int)State.Lock:
|
|
1983
|
+
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
1984
|
+
break;
|
|
1985
|
+
`;
|
|
1986
1986
|
const snippets = extractor.extractStrings(code);
|
|
1987
1987
|
{
|
|
1988
|
-
let
|
|
1989
|
-
expect(
|
|
1990
|
-
expect(
|
|
1991
|
-
expect(
|
|
1992
|
-
|
|
1993
|
-
'
|
|
1988
|
+
let targetSnippet = snippets[0];
|
|
1989
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`));
|
|
1990
|
+
expect(targetSnippet.originalCode).toBe(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`);
|
|
1991
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("灵田{0}级解锁", _model.GetFarmLandUnlockLevel(_landId))`);
|
|
1992
|
+
expect(targetSnippet.literals).toEqual([
|
|
1993
|
+
'灵田{0}级解锁'
|
|
1994
1994
|
]);
|
|
1995
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
1995
1996
|
}
|
|
1996
|
-
})
|
|
1997
|
-
|
|
1998
|
-
|
|
1997
|
+
});
|
|
1998
|
+
|
|
1999
|
+
// 正确识别C# 行注释语句边界, 行注释不能影响上下行的字符串提取
|
|
2000
|
+
test('should handle comment boundary 2', () => {
|
|
2001
|
+
const code = `
|
|
2002
|
+
// klwjfe
|
|
2003
|
+
namespace TestNamespace{
|
|
2004
|
+
// lkwjfe
|
|
2005
|
+
public class FK{
|
|
2006
|
+
// klwf
|
|
2007
|
+
public void TestM(){
|
|
2008
|
+
// 模拟状态变量
|
|
2009
|
+
var _state = (int)State.Lock;
|
|
2010
|
+
// 模拟土地ID变量
|
|
2011
|
+
switch (_state){
|
|
2012
|
+
//上锁
|
|
2013
|
+
case (int)State.Lock:
|
|
2014
|
+
// lkwjefl
|
|
2015
|
+
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
2016
|
+
// klwejf
|
|
2017
|
+
break;
|
|
2018
|
+
// lkwjf
|
|
2019
|
+
}
|
|
2020
|
+
// klwjfel
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
`;
|
|
1999
2025
|
const snippets = extractor.extractStrings(code);
|
|
2000
2026
|
{
|
|
2001
|
-
let
|
|
2002
|
-
expect(
|
|
2003
|
-
expect(
|
|
2004
|
-
expect(
|
|
2005
|
-
|
|
2006
|
-
'
|
|
2027
|
+
let targetSnippet = snippets[0];
|
|
2028
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`));
|
|
2029
|
+
expect(targetSnippet.originalCode).toBe(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`);
|
|
2030
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("灵田{0}级解锁", _model.GetFarmLandUnlockLevel(_landId))`);
|
|
2031
|
+
expect(targetSnippet.literals).toEqual([
|
|
2032
|
+
'灵田{0}级解锁'
|
|
2007
2033
|
]);
|
|
2034
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2008
2035
|
}
|
|
2009
|
-
})
|
|
2010
|
-
});
|
|
2011
|
-
|
|
2012
|
-
describe('基本字符串提取', () => {
|
|
2013
|
-
test('should extract plain strings', () => {
|
|
2014
|
-
const code = 'Console.WriteLine("Hello, world!");';
|
|
2015
|
-
const snippets = extractor.extractStrings(code);
|
|
2016
|
-
|
|
2017
|
-
expect(snippets.length).toBe(1);
|
|
2018
|
-
expect(snippets[0].literals).toEqual(['Hello, world!']);
|
|
2019
|
-
})
|
|
2020
2036
|
});
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2037
|
+
// 正确识别C# 行注释语句边界, 行注释不能影响上下行的字符串提取
|
|
2038
|
+
test('should handle comment boundary 3', () => {
|
|
2039
|
+
const code = `
|
|
2040
|
+
// klwjfe
|
|
2041
|
+
namespace TestNamespace{
|
|
2042
|
+
// lkwjfe
|
|
2043
|
+
public class FK{
|
|
2044
|
+
// wlkjelj
|
|
2045
|
+
private int Llkwe = 23;
|
|
2046
|
+
// lkjlkj
|
|
2047
|
+
private int Dwekl { get; set; } = 23;
|
|
2048
|
+
// jklwef
|
|
2049
|
+
private static int Dwekl { get; set; } = 23;
|
|
2050
|
+
// lkwjeflk
|
|
2051
|
+
public static void TestM(){}
|
|
2052
|
+
// wesd
|
|
2053
|
+
public static void TestM()
|
|
2054
|
+
{
|
|
2055
|
+
}
|
|
2056
|
+
// wesd
|
|
2057
|
+
public static void TestM(){
|
|
2058
|
+
}
|
|
2059
|
+
// klwf
|
|
2060
|
+
public void TestM(){
|
|
2061
|
+
// 模拟状态变量
|
|
2062
|
+
var _state = (int)State.Lock;
|
|
2063
|
+
// 模拟土地ID变量
|
|
2064
|
+
switch (_state){
|
|
2065
|
+
//上锁
|
|
2066
|
+
case (int)State.Lock:
|
|
2067
|
+
// lkwjefl
|
|
2068
|
+
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
2069
|
+
// klwejf
|
|
2070
|
+
break;
|
|
2071
|
+
// lkwjf
|
|
2072
|
+
}
|
|
2073
|
+
// klwjfel
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
`;
|
|
2058
2078
|
const snippets = extractor.extractStrings(code);
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2079
|
+
{
|
|
2080
|
+
let targetSnippet = snippets[0];
|
|
2081
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`));
|
|
2082
|
+
expect(targetSnippet.originalCode).toBe(`$"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁"`);
|
|
2083
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("灵田{0}级解锁", _model.GetFarmLandUnlockLevel(_landId))`);
|
|
2084
|
+
expect(targetSnippet.literals).toEqual([
|
|
2085
|
+
'灵田{0}级解锁'
|
|
2086
|
+
]);
|
|
2087
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2088
|
+
}
|
|
2066
2089
|
});
|
|
2067
2090
|
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
const code =
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, world: {0}", obj.Func1())');
|
|
2085
|
-
})
|
|
2086
|
-
test('should handle .text = assignments with string templates', () => {
|
|
2087
|
-
const code = 'label.text = $"pre{Func()}sub";';
|
|
2088
|
-
const snippets = extractor.extractStrings(code);
|
|
2089
|
-
|
|
2090
|
-
expect(snippets.length).toBe(1);
|
|
2091
|
-
expect(snippets[0].originalCode).toBe('$"pre{Func()}sub"');
|
|
2092
|
-
expect(snippets[0].literals).toContain('pre{0}sub');
|
|
2093
|
-
expect(snippets[0].convertedCode).toBe('Tr.Format("pre{0}sub", Func())');
|
|
2094
|
-
})
|
|
2095
|
-
test('should extract and convert string templates', () => {
|
|
2096
|
-
const code = 'Ljk.Ilk($"Hello, {name}!");';
|
|
2097
|
-
const snippets = extractor.extractStrings(code);
|
|
2098
|
-
|
|
2099
|
-
expect(snippets.length).toBeGreaterThan(0);
|
|
2100
|
-
const snippet = snippets[0];
|
|
2101
|
-
expect(snippet.originalCode).toBe('$"Hello, {name}!"');
|
|
2102
|
-
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
2103
|
-
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
2104
|
-
expect(snippet.isChanged).toBe(true);
|
|
2105
|
-
})
|
|
2106
|
-
test('should handle @$"" and $@"" formats', () => {
|
|
2107
|
-
const code = 'Fcx.Kjl(@$"Hello, {name}!");';
|
|
2108
|
-
const snippets = extractor.extractStrings(code);
|
|
2109
|
-
|
|
2110
|
-
const snippet = snippets[0];
|
|
2111
|
-
expect(snippet.originalCode).toBe('@$"Hello, {name}!"');
|
|
2112
|
-
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
2113
|
-
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
2114
|
-
expect(snippet.isChanged).toBe(true);
|
|
2115
|
-
})
|
|
2116
|
-
test('should handle string template with format specifier', () => {
|
|
2117
|
-
const code = `infoStr += $"最终抗性: {resistReduce:F}\\n";`
|
|
2118
|
-
const snippets = extractor.extractStrings(code);
|
|
2091
|
+
// 正确识别C#文档注释边界, 类、方法、类成员的文档注释需要直接忽略捕获, 不参与字符串表达式提取; 文档注释通常位于类、方法、类成员的定义上方, 文档注释的格式形如: ` /// <xxx> yyy\n /// </xxx>` 或 ` /// <xxx yyy/>`, 其中xxx为标签, yyy为注释内容, `<xxx>`和`</xxx>` 不一定在同一行或不同行, ` /// <xxx> yyy\n` 不一定只有一行; 文档注释通常以`<xxx>`标签开始, 以`</xxx>`标签结束, 或者以 `<xxx ` 开始, 以 `/>` 结束。
|
|
2092
|
+
test('should handle doc comment boundary for class/method/members', () => {
|
|
2093
|
+
const code = `
|
|
2094
|
+
/// <summary>
|
|
2095
|
+
/// "fwef 类注释1"
|
|
2096
|
+
/// $"fwef 类注释2"
|
|
2097
|
+
/// $"fwef 类注释2 {wef}"
|
|
2098
|
+
/// wef $"fwef 类注释2 {wef}" wef
|
|
2099
|
+
/// </summary>
|
|
2100
|
+
/// <sumary "lkwjfelj"/>
|
|
2101
|
+
public partial class TimeLimitedChargeDialog
|
|
2102
|
+
{
|
|
2103
|
+
/// <summary>
|
|
2104
|
+
/// $" Property成员注释 dsvdf {wlpoe}"
|
|
2105
|
+
/// </summary>
|
|
2106
|
+
private int Ljfw { get; set; } = 342;
|
|
2119
2107
|
|
|
2120
|
-
|
|
2121
|
-
|
|
2108
|
+
/// <summary>
|
|
2109
|
+
/// $" Field成员注释 wfewe {vvwe}"
|
|
2110
|
+
/// $" Field成员注释 wfewe {vvwe}" wfe
|
|
2111
|
+
/// </summary>
|
|
2112
|
+
private int Ljfw = 342;
|
|
2122
2113
|
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2114
|
+
/// <summary>
|
|
2115
|
+
///</summary>
|
|
2116
|
+
private int Ljfw = 342;
|
|
2117
|
+
|
|
2118
|
+
/// <summary>
|
|
2119
|
+
/// " wef方法注释 wef"
|
|
2120
|
+
/// $" wef方法注释 wef"
|
|
2121
|
+
/// $" wef方法注释 wef{wef}"
|
|
2122
|
+
/// wfe $" wef方法注释 wef{wef}"
|
|
2123
|
+
/// wfe $" wef方法注释 wef{wef}" wef
|
|
2124
|
+
///wfe $" wef方法注释 wef{wef}" wef
|
|
2125
|
+
/// wefw $" wef方法注释 wef{wef}" we
|
|
2126
|
+
/// </summary>
|
|
2127
|
+
/// <sumary wf $"klwf"/>
|
|
2128
|
+
/// <param name="force">是否重新创建页签列表</param>
|
|
2129
|
+
private void RefreshGoodsInfo()
|
|
2130
|
+
{
|
|
2131
|
+
m_text_timeleft.text = curShop.TimeLimitData.RemainTime() + "后消失";
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
`;
|
|
2131
2135
|
const snippets = extractor.extractStrings(code);
|
|
2132
2136
|
{
|
|
2133
2137
|
let targetSnippet = snippets[0];
|
|
2134
|
-
|
|
2135
|
-
expect(targetSnippet.
|
|
2136
|
-
|
|
2137
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
2138
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2139
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`curShop.TimeLimitData.RemainTime() + "后消失"`));
|
|
2140
|
+
expect(targetSnippet.originalCode).toBe(`curShop.TimeLimitData.RemainTime() + "后消失"`);
|
|
2141
|
+
expect(targetSnippet.convertedCode).toBe(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`);
|
|
2138
2142
|
expect(targetSnippet.literals).toEqual([
|
|
2139
|
-
'
|
|
2143
|
+
'后消失'
|
|
2140
2144
|
]);
|
|
2141
2145
|
expect(targetSnippet.isChanged).toBe(true);
|
|
2142
2146
|
}
|
|
2143
|
-
})
|
|
2144
2147
|
});
|
|
2145
2148
|
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
const code =
|
|
2149
|
+
// 正确识别C#方法参数中的字符串表达式, 支持1到多个形参有默认值的情形
|
|
2150
|
+
test('should handle string expression in method call parameter 1', () => {
|
|
2151
|
+
const code = `
|
|
2152
|
+
namespace FaBao.UI.Comp
|
|
2153
|
+
{
|
|
2154
|
+
public partial class ItemCommonComp
|
|
2155
|
+
{
|
|
2156
|
+
public void BindData(bool needCompare = false)
|
|
2157
|
+
{
|
|
2158
|
+
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
`;
|
|
2149
2163
|
const snippets = extractor.extractStrings(code);
|
|
2150
|
-
|
|
2164
|
+
{
|
|
2165
|
+
let targetSnippet = snippets[0];
|
|
2166
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2167
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}阶", _itemConfig.PillLevel)`));
|
|
2168
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2169
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2170
|
+
expect(targetSnippet.literals).toEqual([
|
|
2171
|
+
'{0}阶'
|
|
2172
|
+
]);
|
|
2173
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2174
|
+
}
|
|
2151
2175
|
expect(snippets.length).toBe(1);
|
|
2152
|
-
// string.Format(...) 形式的字符串表达式, 不需要对提取的字符串表达式进行处理, 也不需要追加 `.TR()`
|
|
2153
|
-
// string.Format(...) 形式包含的字符串表达式, 需要特殊处理, 连带 `string.Format()` 一起捕获存入 originalCode 成员
|
|
2154
|
-
expect(snippets[0].originalCode).toBe('string.Format("Hello, ", name, "!")');
|
|
2155
|
-
expect(snippets[0].convertedCode).toBe('Tr.Format("Hello, ", name, "!")');
|
|
2156
|
-
})
|
|
2157
|
-
test('should convert string.Format to Tr.Format', () => {
|
|
2158
|
-
const code = 'string.Format("Hello, {0}!", name);';
|
|
2159
|
-
const snippets = extractor.extractStrings(code);
|
|
2160
|
-
|
|
2161
|
-
expect(snippets.length).toBeGreaterThan(0);
|
|
2162
|
-
const snippet = snippets[0];
|
|
2163
|
-
expect(snippet.originalCode).toBe('string.Format("Hello, {0}!", name)');
|
|
2164
|
-
expect(snippet.convertedCode).toBe('Tr.Format("Hello, {0}!", name)');
|
|
2165
|
-
expect(snippet.literals).toEqual(['Hello, {0}!']);
|
|
2166
|
-
expect(snippet.isChanged).toBe(true);
|
|
2167
|
-
})
|
|
2168
2176
|
});
|
|
2169
2177
|
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
const code =
|
|
2178
|
+
// 正确识别C#方法参数中的字符串表达式, 支持1到多个形参有默认值的情形
|
|
2179
|
+
test('should handle string expression in method call parameter 2', () => {
|
|
2180
|
+
const code = `
|
|
2181
|
+
namespace FaBao.UI.Comp
|
|
2182
|
+
{
|
|
2183
|
+
public partial class ItemCommonComp
|
|
2184
|
+
{
|
|
2185
|
+
public void BindData(bool needCompare = false, long needCompare2 = 23, float needCompare2 = 324.0)
|
|
2186
|
+
{
|
|
2187
|
+
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
`;
|
|
2173
2192
|
const snippets = extractor.extractStrings(code);
|
|
2174
|
-
|
|
2193
|
+
{
|
|
2194
|
+
let targetSnippet = snippets[0];
|
|
2195
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2196
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}阶", _itemConfig.PillLevel)`));
|
|
2197
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2198
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2199
|
+
expect(targetSnippet.literals).toEqual([
|
|
2200
|
+
'{0}阶'
|
|
2201
|
+
]);
|
|
2202
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2203
|
+
}
|
|
2175
2204
|
expect(snippets.length).toBe(1);
|
|
2176
|
-
|
|
2177
|
-
expect(snippets[0].literals).toContain('pre');
|
|
2178
|
-
expect(snippets[0].literals).toContain('sub');
|
|
2179
|
-
})
|
|
2180
|
-
test('should handle .text = assignments with function calls', () => {
|
|
2181
|
-
const code = 'label.text = Func();';
|
|
2182
|
-
const snippets = extractor.extractStrings(code);
|
|
2205
|
+
});
|
|
2183
2206
|
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2207
|
+
// 正确识别C#方法参数中的字符串表达式, 支持1到多个形参有默认值的情形
|
|
2208
|
+
test('should handle string expression in method call parameter 3', () => {
|
|
2209
|
+
const code = `
|
|
2210
|
+
namespace FaBao.UI.Comp
|
|
2211
|
+
{
|
|
2212
|
+
public partial class ItemCommonComp
|
|
2213
|
+
{
|
|
2214
|
+
public void BindData(string wkle, bool needCompare = false, int needCompare2 = false)
|
|
2215
|
+
{
|
|
2216
|
+
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
`;
|
|
2190
2221
|
const snippets = extractor.extractStrings(code);
|
|
2191
|
-
|
|
2222
|
+
{
|
|
2223
|
+
let targetSnippet = snippets[0];
|
|
2224
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2225
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}阶", _itemConfig.PillLevel)`));
|
|
2226
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2227
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2228
|
+
expect(targetSnippet.literals).toEqual([
|
|
2229
|
+
'{0}阶'
|
|
2230
|
+
]);
|
|
2231
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2232
|
+
}
|
|
2192
2233
|
expect(snippets.length).toBe(1);
|
|
2193
|
-
|
|
2194
|
-
expect(snippets[0].convertedCode).toBe('Func().TR() + Func().TR()');
|
|
2195
|
-
})
|
|
2196
|
-
test('should handle .text = assignments with string.Format', () => {
|
|
2197
|
-
const code = 'label.text = string.Format("pre{0:F2}{1}", Func(), "sub") + other;';
|
|
2198
|
-
const snippets = extractor.extractStrings(code);
|
|
2234
|
+
});
|
|
2199
2235
|
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2236
|
+
// 正确提取C#方法参数中的字符串表达式信息, 支持1到多个形参有默认值的情形
|
|
2237
|
+
test('should handle string expression in method call parameter 4', () => {
|
|
2238
|
+
const code = `
|
|
2239
|
+
namespace FaBao.UI.Comp
|
|
2240
|
+
{
|
|
2241
|
+
public partial class ItemCommonComp
|
|
2242
|
+
{
|
|
2243
|
+
public void BindData(string wkle = "11111", bool needCompare = false, int needCompare2 = false)
|
|
2244
|
+
{
|
|
2245
|
+
}
|
|
2208
2246
|
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
expect(snippet.convertedCode).toBe('"Test".TR()');
|
|
2213
|
-
expect(snippet.literals).toEqual(['Test']);
|
|
2214
|
-
expect(snippet.isChanged).toBe(true);
|
|
2215
|
-
})
|
|
2216
|
-
test('should handle .text = with Tr.Format', () => {
|
|
2217
|
-
const code = 'label.text = Tr.Format("pre", Func(), "sub") + other;';
|
|
2218
|
-
const snippets = extractor.extractStrings(code);
|
|
2247
|
+
public void BindData(string wkle = "22", string wkle = "werwer", bool needCompare = false, string wkle = "wefwewef31f", int needCompare2 = false, string wkle = "df223")
|
|
2248
|
+
{
|
|
2249
|
+
}
|
|
2219
2250
|
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2251
|
+
public void BindData(string wkle = "(*&%\\\\*(@Fwfe))&(")
|
|
2252
|
+
{
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
public void BindData(string we, string wkle = "aaaaa", bool needCompare = false, int needCompare2 = false)
|
|
2256
|
+
{
|
|
2257
|
+
m_text_level.text = Tr.Format("{0}阶", _itemConfig.PillLevel);
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2230
2261
|
`;
|
|
2231
2262
|
const snippets = extractor.extractStrings(code);
|
|
2232
2263
|
{
|
|
2233
|
-
let
|
|
2234
|
-
|
|
2235
|
-
expect(
|
|
2236
|
-
expect(
|
|
2237
|
-
|
|
2264
|
+
let targetSnippet = snippets[0];
|
|
2265
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2266
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"11111"`));
|
|
2267
|
+
expect(targetSnippet.originalCode).toBe(`"11111"`);
|
|
2268
|
+
expect(targetSnippet.convertedCode).toBe(`"11111"`);
|
|
2269
|
+
expect(targetSnippet.literals).toEqual([
|
|
2270
|
+
'11111'
|
|
2271
|
+
]);
|
|
2272
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2273
|
+
}
|
|
2274
|
+
{
|
|
2275
|
+
let targetSnippet = snippets[1];
|
|
2276
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2277
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"22"`));
|
|
2278
|
+
expect(targetSnippet.originalCode).toBe(`"22"`);
|
|
2279
|
+
expect(targetSnippet.convertedCode).toBe(`"22"`);
|
|
2280
|
+
expect(targetSnippet.literals).toEqual([
|
|
2281
|
+
'22'
|
|
2282
|
+
]);
|
|
2283
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2284
|
+
}
|
|
2285
|
+
{
|
|
2286
|
+
let targetSnippet = snippets[2];
|
|
2287
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2288
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"werwer"`));
|
|
2289
|
+
expect(targetSnippet.originalCode).toBe(`"werwer"`);
|
|
2290
|
+
expect(targetSnippet.convertedCode).toBe(`"werwer"`);
|
|
2291
|
+
expect(targetSnippet.literals).toEqual([
|
|
2292
|
+
'werwer'
|
|
2293
|
+
]);
|
|
2294
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2295
|
+
}
|
|
2296
|
+
{
|
|
2297
|
+
let targetSnippet = snippets[3];
|
|
2298
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2299
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"wefwewef31f"`));
|
|
2300
|
+
expect(targetSnippet.originalCode).toBe(`"wefwewef31f"`);
|
|
2301
|
+
expect(targetSnippet.convertedCode).toBe(`"wefwewef31f"`);
|
|
2302
|
+
expect(targetSnippet.literals).toEqual([
|
|
2303
|
+
'wefwewef31f'
|
|
2304
|
+
]);
|
|
2305
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2306
|
+
}
|
|
2307
|
+
{
|
|
2308
|
+
let targetSnippet = snippets[4];
|
|
2309
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2310
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"df223"`));
|
|
2311
|
+
expect(targetSnippet.originalCode).toBe(`"df223"`);
|
|
2312
|
+
expect(targetSnippet.convertedCode).toBe(`"df223"`);
|
|
2313
|
+
expect(targetSnippet.literals).toEqual([
|
|
2314
|
+
'df223'
|
|
2315
|
+
]);
|
|
2316
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2317
|
+
}
|
|
2318
|
+
{
|
|
2319
|
+
let targetSnippet = snippets[5];
|
|
2320
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2321
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"(*&%\\\\*(@Fwfe))&("`));
|
|
2322
|
+
expect(targetSnippet.originalCode).toBe(`"(*&%\\\\*(@Fwfe))&("`);
|
|
2323
|
+
expect(targetSnippet.convertedCode).toBe(`"(*&%\\\\*(@Fwfe))&("`);
|
|
2324
|
+
expect(targetSnippet.literals).toEqual([
|
|
2325
|
+
'(*&%\\\\*(@Fwfe))&('
|
|
2238
2326
|
]);
|
|
2327
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2239
2328
|
}
|
|
2240
2329
|
{
|
|
2241
|
-
let
|
|
2242
|
-
|
|
2243
|
-
expect(
|
|
2244
|
-
expect(
|
|
2245
|
-
|
|
2330
|
+
let targetSnippet = snippets[6];
|
|
2331
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2332
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"aaaaa"`));
|
|
2333
|
+
expect(targetSnippet.originalCode).toBe(`"aaaaa"`);
|
|
2334
|
+
expect(targetSnippet.convertedCode).toBe(`"aaaaa"`);
|
|
2335
|
+
expect(targetSnippet.literals).toEqual([
|
|
2336
|
+
'aaaaa'
|
|
2246
2337
|
]);
|
|
2338
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2339
|
+
}
|
|
2340
|
+
{
|
|
2341
|
+
let targetSnippet = snippets[7];
|
|
2342
|
+
// 类注释和方法注释不参与字符串表达式提取, 不影响字符串提取结果
|
|
2343
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}阶", _itemConfig.PillLevel)`));
|
|
2344
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2345
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}阶", _itemConfig.PillLevel)`);
|
|
2346
|
+
expect(targetSnippet.literals).toEqual([
|
|
2347
|
+
'{0}阶'
|
|
2348
|
+
]);
|
|
2349
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2247
2350
|
}
|
|
2248
|
-
})
|
|
2249
2351
|
});
|
|
2250
2352
|
|
|
2251
|
-
|
|
2252
|
-
|
|
2353
|
+
// 需要正确识别C#代码中 `if` 语句边界 和 创建对象表达式的边界, 识别 `if` 语句前、中、后部分中的字符串表达式
|
|
2354
|
+
test('should handle if border and object creation expression border', () => {
|
|
2253
2355
|
const code = `
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
m_btn_fxx_wf.title = $"Hello, {name}!";
|
|
2260
|
-
`;
|
|
2261
|
-
const snippets = extractor.extractStrings(code);
|
|
2262
|
-
{
|
|
2263
|
-
let snippet = snippets[0];
|
|
2264
|
-
expect(snippet.originalIndex).toBe(code.indexOf('"lkwjelkfj1"'));
|
|
2265
|
-
expect(snippet.originalCode).toBe('"lkwjelkfj1"');
|
|
2266
|
-
// `buy` 不符合 `m_btn_` 开头的条件, 不需要强制加 `.TR()`
|
|
2267
|
-
expect(snippet.convertedCode).toBe('"lkwjelkfj1"');
|
|
2268
|
-
expect(snippet.literals).toContain('lkwjelkfj1');
|
|
2269
|
-
expect(snippet.isChanged).toBe(false);
|
|
2270
|
-
}
|
|
2356
|
+
namespace FaBao.UI.MainUI
|
|
2357
|
+
{
|
|
2358
|
+
public partial class SpellUpgradeDialog
|
|
2359
|
+
{
|
|
2360
|
+
private async void OnBtnUpgrade()
|
|
2271
2361
|
{
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
expect(snippet.isChanged).toBe(false);
|
|
2362
|
+
// new SpellCard_Action_UpgradeSpellCard(_symbolCard.Id) 被方法调用传参的 () 包裹, 因此已经构成了完整的对象创建表达式
|
|
2363
|
+
if (await this.GetModel<SpellCardModel>().DispatchAction(new SpellCard_Action_UpgradeSpellCard(_symbolCard.Id)))
|
|
2364
|
+
{
|
|
2365
|
+
//升级成功后刷新界面
|
|
2366
|
+
m_text_level.text = Tr.Format("{0}级", _symbolCard.Level);
|
|
2367
|
+
}
|
|
2279
2368
|
}
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
`;
|
|
2372
|
+
const snippets = extractor.extractStrings(code);
|
|
2280
2373
|
{
|
|
2281
|
-
let
|
|
2282
|
-
|
|
2283
|
-
expect(
|
|
2284
|
-
|
|
2285
|
-
expect(
|
|
2286
|
-
expect(
|
|
2287
|
-
|
|
2374
|
+
let targetSnippet = snippets[0];
|
|
2375
|
+
// 需要正确识别 `if` 语句边界, 识别 `if` 语句前、中、后部分中的字符串表达式
|
|
2376
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`Tr.Format("{0}级", _symbolCard.Level)`));
|
|
2377
|
+
expect(targetSnippet.originalCode).toBe(`Tr.Format("{0}级", _symbolCard.Level)`);
|
|
2378
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}级", _symbolCard.Level)`);
|
|
2379
|
+
expect(targetSnippet.literals).toEqual([
|
|
2380
|
+
'{0}级'
|
|
2381
|
+
]);
|
|
2382
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2288
2383
|
}
|
|
2384
|
+
expect(snippets.length).toBe(1);
|
|
2385
|
+
});
|
|
2386
|
+
|
|
2387
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2388
|
+
test('should handle class member initialization assignment with anonymous function 1', () => {
|
|
2389
|
+
const code = `
|
|
2390
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2391
|
+
{
|
|
2392
|
+
Title = "提示",
|
|
2393
|
+
ConfirmCallback = async () =>
|
|
2394
|
+
{
|
|
2395
|
+
//灵纹一键下阵
|
|
2396
|
+
if (await this.GetModel<CardModel>().DispatchAction(new Rune_Action_CleanRune(_sutraCardData.Card.Id)))
|
|
2397
|
+
{
|
|
2398
|
+
Toast.Info("卸载成功");
|
|
2399
|
+
}
|
|
2400
|
+
},
|
|
2401
|
+
CancelText = "取消",
|
|
2402
|
+
}).Forget();
|
|
2403
|
+
`;
|
|
2404
|
+
const snippets = extractor.extractStrings(code);
|
|
2289
2405
|
{
|
|
2290
|
-
let
|
|
2291
|
-
expect(
|
|
2292
|
-
expect(
|
|
2293
|
-
|
|
2294
|
-
expect(
|
|
2295
|
-
|
|
2296
|
-
|
|
2406
|
+
let targetSnippet = snippets[0];
|
|
2407
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"提示"`));
|
|
2408
|
+
expect(targetSnippet.originalCode).toBe(`"提示"`);
|
|
2409
|
+
expect(targetSnippet.convertedCode).toBe(`"提示"`);
|
|
2410
|
+
expect(targetSnippet.literals).toEqual([
|
|
2411
|
+
'提示'
|
|
2412
|
+
]);
|
|
2413
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2297
2414
|
}
|
|
2298
2415
|
{
|
|
2299
|
-
let
|
|
2300
|
-
|
|
2301
|
-
expect(
|
|
2302
|
-
|
|
2303
|
-
expect(
|
|
2304
|
-
expect(
|
|
2305
|
-
|
|
2416
|
+
let targetSnippet = snippets[1];
|
|
2417
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2418
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"卸载成功"`));
|
|
2419
|
+
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
2420
|
+
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
2421
|
+
expect(targetSnippet.literals).toEqual([
|
|
2422
|
+
'卸载成功'
|
|
2423
|
+
]);
|
|
2424
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2306
2425
|
}
|
|
2307
2426
|
{
|
|
2308
|
-
let
|
|
2309
|
-
expect(
|
|
2310
|
-
expect(
|
|
2311
|
-
|
|
2312
|
-
expect(
|
|
2313
|
-
|
|
2314
|
-
|
|
2427
|
+
let targetSnippet = snippets[2];
|
|
2428
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"取消"`));
|
|
2429
|
+
expect(targetSnippet.originalCode).toBe(`"取消"`);
|
|
2430
|
+
expect(targetSnippet.convertedCode).toBe(`"取消"`);
|
|
2431
|
+
expect(targetSnippet.literals).toEqual([
|
|
2432
|
+
'取消'
|
|
2433
|
+
]);
|
|
2434
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2315
2435
|
}
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2436
|
+
});
|
|
2437
|
+
|
|
2438
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2439
|
+
test('should handle class member initialization assignment with anonymous function 2', () => {
|
|
2319
2440
|
const code = `
|
|
2320
|
-
|
|
2321
|
-
{
|
|
2322
|
-
case Data.Match.RoomState.IsDismiss:
|
|
2323
|
-
m_btn_join.title = "已解散";
|
|
2324
|
-
m_btn_join.enabled = false;
|
|
2325
|
-
grayed = true;
|
|
2326
|
-
break;
|
|
2327
|
-
case Data.Match.RoomState.Rejected:
|
|
2441
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2328
2442
|
{
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
m_dd_join.text = "已到期";
|
|
2335
|
-
break;
|
|
2336
|
-
default:
|
|
2337
|
-
m_btn_join.title = "申请";
|
|
2338
|
-
m_btn_joi23n.title = $"申请{Kjf}";
|
|
2339
|
-
break;
|
|
2340
|
-
}
|
|
2443
|
+
ConfirmCallback = async () =>
|
|
2444
|
+
{
|
|
2445
|
+
Toast.Info("卸载成功");
|
|
2446
|
+
},
|
|
2447
|
+
}).Forget();
|
|
2341
2448
|
`;
|
|
2342
2449
|
const snippets = extractor.extractStrings(code);
|
|
2343
2450
|
{
|
|
2344
|
-
let
|
|
2345
|
-
|
|
2346
|
-
expect(
|
|
2347
|
-
expect(
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
{
|
|
2352
|
-
let snippet = snippets[1];
|
|
2353
|
-
expect(snippet.originalCode).toBe('$"被拒绝{Kff}"');
|
|
2354
|
-
expect(snippet.convertedCode).toBe('Tr.Format("被拒绝{0}", Kff)');
|
|
2355
|
-
expect(snippet.literals).toEqual([
|
|
2356
|
-
'被拒绝{0}'
|
|
2451
|
+
let targetSnippet = snippets[0];
|
|
2452
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2453
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"卸载成功"`));
|
|
2454
|
+
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
2455
|
+
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
2456
|
+
expect(targetSnippet.literals).toEqual([
|
|
2457
|
+
'卸载成功'
|
|
2357
2458
|
]);
|
|
2459
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2358
2460
|
}
|
|
2461
|
+
});
|
|
2462
|
+
|
|
2463
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2464
|
+
test('should handle class member initialization assignment with anonymous function 3', () => {
|
|
2465
|
+
const code = `
|
|
2466
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2467
|
+
{
|
|
2468
|
+
ConfirmCallback = (int qwfewe) =>
|
|
2469
|
+
{
|
|
2470
|
+
Toast.Info($"卸载成功: {qwfewe}");
|
|
2471
|
+
},
|
|
2472
|
+
}).Forget();
|
|
2473
|
+
`;
|
|
2474
|
+
const snippets = extractor.extractStrings(code);
|
|
2359
2475
|
{
|
|
2360
|
-
let
|
|
2361
|
-
|
|
2362
|
-
expect(
|
|
2363
|
-
expect(
|
|
2364
|
-
|
|
2476
|
+
let targetSnippet = snippets[0];
|
|
2477
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2478
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"卸载成功: {qwfewe}"`));
|
|
2479
|
+
expect(targetSnippet.originalCode).toBe(`$"卸载成功: {qwfewe}"`);
|
|
2480
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("卸载成功: {0}", qwfewe)`);
|
|
2481
|
+
expect(targetSnippet.literals).toEqual([
|
|
2482
|
+
'卸载成功: {0}'
|
|
2365
2483
|
]);
|
|
2484
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2366
2485
|
}
|
|
2486
|
+
});
|
|
2487
|
+
|
|
2488
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2489
|
+
test('should handle class member initialization assignment with anonymous function 4', () => {
|
|
2490
|
+
const code = `
|
|
2491
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2492
|
+
{
|
|
2493
|
+
ConfirmCallback = async () => Toast.Info("卸载成功"),
|
|
2494
|
+
}).Forget();
|
|
2495
|
+
`;
|
|
2496
|
+
const snippets = extractor.extractStrings(code);
|
|
2367
2497
|
{
|
|
2368
|
-
let
|
|
2369
|
-
|
|
2370
|
-
expect(
|
|
2371
|
-
expect(
|
|
2372
|
-
|
|
2498
|
+
let targetSnippet = snippets[0];
|
|
2499
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2500
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"卸载成功"`));
|
|
2501
|
+
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
2502
|
+
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
2503
|
+
expect(targetSnippet.literals).toEqual([
|
|
2504
|
+
'卸载成功'
|
|
2373
2505
|
]);
|
|
2506
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2374
2507
|
}
|
|
2508
|
+
});
|
|
2509
|
+
|
|
2510
|
+
// 需要正确识别C#代码中的匿名函数, 匿名函数中的字符串表达式也同样需要提取; 匿名函数通常以 `0到多个修饰词 (可选参数列表) => { ... }` 或者 `0到多个修饰词 (可选参数列表) => 一句表达式` 形式定义实现.
|
|
2511
|
+
test('should handle class member initialization assignment with anonymous function 5', () => {
|
|
2512
|
+
const code = `
|
|
2513
|
+
FUISys.Instance.ShowLayer<MainConfirmDialog>(UISceneType.Main, new MainConfirmDialog.MainConfirmDialogParam()
|
|
2514
|
+
{
|
|
2515
|
+
ConfirmCallback = () => Toast.Info("卸载成功"),
|
|
2516
|
+
}).Forget();
|
|
2517
|
+
`;
|
|
2518
|
+
const snippets = extractor.extractStrings(code);
|
|
2375
2519
|
{
|
|
2376
|
-
let
|
|
2377
|
-
|
|
2378
|
-
expect(
|
|
2379
|
-
expect(
|
|
2380
|
-
|
|
2520
|
+
let targetSnippet = snippets[0];
|
|
2521
|
+
// 需要正确识别C#代码中类成员初始化赋值时, 给成员赋值匿名函数时, 匿名函数中的字符串表达式也需要提取
|
|
2522
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`"卸载成功"`));
|
|
2523
|
+
expect(targetSnippet.originalCode).toBe(`"卸载成功"`);
|
|
2524
|
+
expect(targetSnippet.convertedCode).toBe(`"卸载成功"`);
|
|
2525
|
+
expect(targetSnippet.literals).toEqual([
|
|
2526
|
+
'卸载成功'
|
|
2381
2527
|
]);
|
|
2528
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2382
2529
|
}
|
|
2383
|
-
})
|
|
2384
2530
|
});
|
|
2385
2531
|
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
const code =
|
|
2532
|
+
// 测试处理 `xxx.text = yyy;` 形式赋值语句, 以 `.text =` 给 `text` 成员赋值的表达式中, `yyy` 部分必定是字符串表达式; 如果`yyy`中不存在字符串, 则`yyy` 中以 `+` 连接的表达式需要加上 `.TR()`; 如果 `yyy` 是作为值表达式整体(必定返回字符串类型值), 也需要追加 `.TR()`。
|
|
2533
|
+
test('should handle .text = format 1', () => {
|
|
2534
|
+
const code = `m_text_iwff.text = info ;`;
|
|
2389
2535
|
const snippets = extractor.extractStrings(code);
|
|
2536
|
+
{
|
|
2537
|
+
let targetSnippet = snippets[0];
|
|
2538
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`info`));
|
|
2539
|
+
expect(targetSnippet.originalCode).toBe(`info`);
|
|
2540
|
+
expect(targetSnippet.convertedCode).toBe(`info.TR()`);
|
|
2541
|
+
expect(targetSnippet.literals).toEqual([
|
|
2542
|
+
]);
|
|
2543
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2544
|
+
}
|
|
2545
|
+
});
|
|
2390
2546
|
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
})
|
|
2395
|
-
test('should handle string concatenations', () => {
|
|
2396
|
-
const code = 'var wkleee = "Hello, " + name + "!";';
|
|
2547
|
+
// 测试处理 `xxx.text = yyy;` 形式赋值语句, 以 `.text =` 给 `text` 成员赋值的表达式中, `yyy` 部分必定是字符串表达式; 如果`yyy`中不存在字符串, 则`yyy` 中以 `+` 连接的表达式需要加上 `.TR()`; 如果 `yyy` 是作为值表达式整体(必定返回字符串类型值), 也需要追加 `.TR()`。
|
|
2548
|
+
test('should handle .text = format 2', () => {
|
|
2549
|
+
const code = `m_text_info.text = info1.member1 + info2.member2;`;
|
|
2397
2550
|
const snippets = extractor.extractStrings(code);
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2551
|
+
{
|
|
2552
|
+
let targetSnippet = snippets[0];
|
|
2553
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`info1.member1 + info2.member2`));
|
|
2554
|
+
expect(targetSnippet.originalCode).toBe(`info1.member1 + info2.member2`);
|
|
2555
|
+
expect(targetSnippet.convertedCode).toBe(`info1.member1.TR() + info2.member2.TR()`);
|
|
2556
|
+
expect(targetSnippet.literals).toEqual([
|
|
2557
|
+
]);
|
|
2558
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2559
|
+
}
|
|
2406
2560
|
});
|
|
2407
2561
|
|
|
2408
|
-
|
|
2409
|
-
|
|
2562
|
+
// 处理字符串出现在赋值表达式的 `=` 左边(左值表达式)的情况
|
|
2563
|
+
test('should handle right value expression', () => {
|
|
2410
2564
|
const code = `
|
|
2411
|
-
|
|
2412
|
-
Toast.Info($"灵田{_model.GetFarmLandUnlockLevel(_landId)}级解锁");
|
|
2413
|
-
break;
|
|
2565
|
+
((GLoader)GetChild($"m_loader_dailyItem{i + 1}")).url = FUISys.Instance.GetIconUrl(ItemTable.GetConfigById(_cardConfig.EveryDayAwards[i].ResId).Icon);
|
|
2414
2566
|
`;
|
|
2415
2567
|
const snippets = extractor.extractStrings(code);
|
|
2416
2568
|
{
|
|
2417
2569
|
let targetSnippet = snippets[0];
|
|
2418
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"
|
|
2419
|
-
expect(targetSnippet.originalCode).toBe(`$"
|
|
2420
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("
|
|
2570
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"m_loader_dailyItem{i + 1}"`));
|
|
2571
|
+
expect(targetSnippet.originalCode).toBe(`$"m_loader_dailyItem{i + 1}"`); // 左边表达式函数调用参数中的字符串表达式
|
|
2572
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("m_loader_dailyItem{0}", i + 1)`);
|
|
2421
2573
|
expect(targetSnippet.literals).toEqual([
|
|
2422
|
-
|
|
2574
|
+
`m_loader_dailyItem{0}`
|
|
2423
2575
|
]);
|
|
2424
2576
|
expect(targetSnippet.isChanged).toBe(true);
|
|
2425
2577
|
}
|
|
2426
|
-
})
|
|
2427
|
-
});
|
|
2428
|
-
|
|
2429
|
-
describe('转义字符与特殊字符串处理', () => {
|
|
2430
|
-
test('should handle escaped quotes in strings', () => {
|
|
2431
|
-
const code = 'Debug.Log("aaa\\\"bbb\\\"c\\\"d\\\\\\"cc");';
|
|
2432
|
-
const snippets = extractor.extractStrings(code);
|
|
2433
|
-
|
|
2434
2578
|
expect(snippets.length).toBe(1);
|
|
2435
|
-
|
|
2436
|
-
expect(snippets[0].convertedCode).toBe('"aaa\\\"bbb\\\"c\\\"d\\\\\\"cc"');
|
|
2437
|
-
// 由于JavaScript字符串转义的复杂性,我们只检查是否提取了字符串
|
|
2438
|
-
expect(snippets[0].literals).toEqual(['aaa\\\"bbb\\\"c\\\"d\\\\\\"cc']);
|
|
2439
|
-
})
|
|
2440
|
-
test('should handle escaped strings', () => {
|
|
2441
|
-
const code = 'a.text = "aaa\\"bbb\\"c\\"d\\\\\\"cc";';
|
|
2442
|
-
const snippets = extractor.extractStrings(code);
|
|
2579
|
+
});
|
|
2443
2580
|
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
})
|
|
2450
|
-
test('should handle special characters in string expression of return sentence', () => {
|
|
2451
|
-
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
2581
|
+
// 支持处理字符串里出现各种特殊符号的情况
|
|
2582
|
+
test('should handle special characters in string 8', () => {
|
|
2583
|
+
const code = `
|
|
2584
|
+
m_btn_paid.text = $"<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{paidConfig.Quantity}";
|
|
2585
|
+
`;
|
|
2452
2586
|
const snippets = extractor.extractStrings(code);
|
|
2453
2587
|
{
|
|
2454
|
-
let targetSnippet = snippets[
|
|
2455
|
-
|
|
2456
|
-
expect(targetSnippet.
|
|
2457
|
-
expect(targetSnippet.
|
|
2458
|
-
expect(targetSnippet.convertedCode).toBe(`"5. {}abcdefghijklmnopqrstuvwxyz\`-=[];\',./~!@#$%^&*()_+|:\\"<>?1234567890\\\\"`);
|
|
2588
|
+
let targetSnippet = snippets[0];
|
|
2589
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{paidConfig.Quantity}"`));
|
|
2590
|
+
expect(targetSnippet.originalCode).toBe(`$"<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{paidConfig.Quantity}"`);
|
|
2591
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{0}", paidConfig.Quantity)`);
|
|
2459
2592
|
expect(targetSnippet.literals).toEqual([
|
|
2460
|
-
'
|
|
2593
|
+
`<img src='ui://a0w66rlc7bhfusff'/ width = '70' height = '70'>{0}`
|
|
2461
2594
|
]);
|
|
2462
|
-
expect(targetSnippet.isChanged).toBe(
|
|
2595
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2463
2596
|
}
|
|
2464
|
-
|
|
2597
|
+
expect(snippets.length).toBe(1);
|
|
2465
2598
|
});
|
|
2466
2599
|
|
|
2467
|
-
|
|
2468
|
-
|
|
2600
|
+
// 处理赋值表达式 `=` 左右两边(左值表达式和右值表达式)都存在字符串的情况
|
|
2601
|
+
test('should handle assignment expression with both sides strings', () => {
|
|
2469
2602
|
const code = `
|
|
2470
|
-
|
|
2471
|
-
/// "fwef 类注释1"
|
|
2472
|
-
/// $"fwef 类注释2"
|
|
2473
|
-
/// $"fwef 类注释2 {wef}"
|
|
2474
|
-
/// wef $"fwef 类注释2 {wef}" wef
|
|
2475
|
-
/// </summary>
|
|
2476
|
-
/// <sumary "lkwjfelj"/>
|
|
2477
|
-
public partial class TimeLimitedChargeDialog
|
|
2478
|
-
{
|
|
2479
|
-
/// <summary>
|
|
2480
|
-
/// $" Property成员注释 dsvdf {wlpoe}"
|
|
2481
|
-
/// </summary>
|
|
2482
|
-
private int Ljfw { get; set; } = 342;
|
|
2483
|
-
|
|
2484
|
-
/// <summary>
|
|
2485
|
-
/// $" Field成员注释 wfewe {vvwe}"
|
|
2486
|
-
/// $" Field成员注释 wfewe {vvwe}" wfe
|
|
2487
|
-
/// </summary>
|
|
2488
|
-
private int Ljfw = 342;
|
|
2489
|
-
|
|
2490
|
-
/// <summary>
|
|
2491
|
-
///</summary>
|
|
2492
|
-
private int Ljfw = 342;
|
|
2493
|
-
|
|
2494
|
-
/// <summary>
|
|
2495
|
-
/// " wef方法注释 wef"
|
|
2496
|
-
/// $" wef方法注释 wef"
|
|
2497
|
-
/// $" wef方法注释 wef{wef}"
|
|
2498
|
-
/// wfe $" wef方法注释 wef{wef}"
|
|
2499
|
-
/// wfe $" wef方法注释 wef{wef}" wef
|
|
2500
|
-
///wfe $" wef方法注释 wef{wef}" wef
|
|
2501
|
-
/// wefw $" wef方法注释 wef{wef}" we
|
|
2502
|
-
/// </summary>
|
|
2503
|
-
/// <sumary wf $"klwf"/>
|
|
2504
|
-
/// <param name="force">是否重新创建页签列表</param>
|
|
2505
|
-
private void RefreshGoodsInfo()
|
|
2506
|
-
{
|
|
2507
|
-
m_text_timeleft.text = curShop.TimeLimitData.RemainTime() + "后消失";
|
|
2508
|
-
}
|
|
2509
|
-
}
|
|
2603
|
+
((GTextField)GetChild($"m_text_dailyCount{i + 1}")).text = $"x{_cardConfig.EveryDayAwards[i].Count}";
|
|
2510
2604
|
`;
|
|
2511
2605
|
const snippets = extractor.extractStrings(code);
|
|
2512
2606
|
{
|
|
2513
2607
|
let targetSnippet = snippets[0];
|
|
2514
|
-
|
|
2515
|
-
expect(targetSnippet.
|
|
2516
|
-
expect(targetSnippet.
|
|
2517
|
-
expect(targetSnippet.convertedCode).toBe(`curShop.TimeLimitData.RemainTime().TR() + "后消失".TR()`);
|
|
2608
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"m_text_dailyCount{i + 1}"`));
|
|
2609
|
+
expect(targetSnippet.originalCode).toBe(`$"m_text_dailyCount{i + 1}"`);
|
|
2610
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("m_text_dailyCount{0}", i + 1)`);
|
|
2518
2611
|
expect(targetSnippet.literals).toEqual([
|
|
2519
|
-
|
|
2612
|
+
`m_text_dailyCount{0}`
|
|
2520
2613
|
]);
|
|
2521
2614
|
expect(targetSnippet.isChanged).toBe(true);
|
|
2522
2615
|
}
|
|
2523
|
-
|
|
2616
|
+
{
|
|
2617
|
+
let targetSnippet = snippets[1];
|
|
2618
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"x{_cardConfig.EveryDayAwards[i].Count}"`));
|
|
2619
|
+
expect(targetSnippet.originalCode).toBe(`$"x{_cardConfig.EveryDayAwards[i].Count}"`);
|
|
2620
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("x{0}", _cardConfig.EveryDayAwards[i].Count)`);
|
|
2621
|
+
expect(targetSnippet.literals).toEqual([
|
|
2622
|
+
`x{0}`
|
|
2623
|
+
]);
|
|
2624
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2625
|
+
}
|
|
2626
|
+
expect(snippets.length).toBe(2);
|
|
2524
2627
|
});
|
|
2525
2628
|
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
const code =
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
expect(snippets.length).toBe(1);
|
|
2532
|
-
expect(snippets[0].originalCode).toBe('"Test property" + "Test property2"');
|
|
2533
|
-
expect(snippets[0].convertedCode).toBe('"Test property".TR() + "Test property2".TR()');
|
|
2534
|
-
})
|
|
2535
|
-
test('should handle complex text assignments', () => {
|
|
2536
|
-
const code = 'label.text = string.Format("pre{0}sub", Func()) + other;';
|
|
2537
|
-
const snippets = extractor.extractStrings(code);
|
|
2538
|
-
|
|
2539
|
-
const snippet = snippets[0];
|
|
2540
|
-
expect(snippet.originalCode).toBe('string.Format("pre{0}sub", Func()) + other');
|
|
2541
|
-
expect(snippet.convertedCode).toBe('Tr.Format("pre{0}sub", Func()) + other.TR()');
|
|
2542
|
-
expect(snippet.literals).toEqual(['pre{0}sub']);
|
|
2543
|
-
expect(snippet.isChanged).toBe(true);
|
|
2544
|
-
})
|
|
2545
|
-
test('should handle member initial assignment', () => {
|
|
2546
|
-
const code = readFileSync("test/TestSpecialString.cs", "utf8");
|
|
2629
|
+
// 支持处理字符串里出现各种特殊符号的情况
|
|
2630
|
+
test('should handle special characters in string 9', () => {
|
|
2631
|
+
const code = `
|
|
2632
|
+
(GetChild($"m_textAnime{GetNextNumber()}") as TurtleTextAnimeComp)?.SetText(word);
|
|
2633
|
+
`;
|
|
2547
2634
|
const snippets = extractor.extractStrings(code);
|
|
2548
2635
|
{
|
|
2549
2636
|
let targetSnippet = snippets[0];
|
|
2550
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
2551
|
-
expect(targetSnippet.originalCode).toBe(
|
|
2552
|
-
expect(targetSnippet.convertedCode).toBe(`"
|
|
2637
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"m_textAnime{GetNextNumber()}"`));
|
|
2638
|
+
expect(targetSnippet.originalCode).toBe(`$"m_textAnime{GetNextNumber()}"`);
|
|
2639
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("m_textAnime{0}", GetNextNumber())`);
|
|
2553
2640
|
expect(targetSnippet.literals).toEqual([
|
|
2554
|
-
|
|
2641
|
+
`m_textAnime{0}`
|
|
2555
2642
|
]);
|
|
2556
|
-
expect(targetSnippet.isChanged).toBe(
|
|
2643
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2557
2644
|
}
|
|
2645
|
+
expect(snippets.length).toBe(1);
|
|
2646
|
+
});
|
|
2647
|
+
|
|
2648
|
+
// 支持处理字符串里出现各种特殊符号的情况
|
|
2649
|
+
test('should handle special characters in string 10', () => {
|
|
2650
|
+
const code = `
|
|
2651
|
+
(GetChild($"m_textAnime{GetNextNumber()}") as TurtleTextAnimeComp)?.SetText(word);
|
|
2652
|
+
`;
|
|
2653
|
+
const snippets = extractor.extractStrings(code);
|
|
2558
2654
|
{
|
|
2559
|
-
let targetSnippet = snippets[
|
|
2560
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
2561
|
-
expect(targetSnippet.originalCode).toBe(
|
|
2562
|
-
expect(targetSnippet.convertedCode).toBe(`"
|
|
2655
|
+
let targetSnippet = snippets[0];
|
|
2656
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"m_textAnime{GetNextNumber()}"`));
|
|
2657
|
+
expect(targetSnippet.originalCode).toBe(`$"m_textAnime{GetNextNumber()}"`);
|
|
2658
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("m_textAnime{0}", GetNextNumber())`);
|
|
2563
2659
|
expect(targetSnippet.literals).toEqual([
|
|
2564
|
-
|
|
2660
|
+
`m_textAnime{0}`
|
|
2565
2661
|
]);
|
|
2566
|
-
expect(targetSnippet.isChanged).toBe(
|
|
2662
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2567
2663
|
}
|
|
2664
|
+
expect(snippets.length).toBe(1);
|
|
2665
|
+
});
|
|
2666
|
+
|
|
2667
|
+
// 修正字符串表达式捕获范围
|
|
2668
|
+
test('should handle string expression capture range 1', () => {
|
|
2669
|
+
const code = `
|
|
2670
|
+
(GetChild($"vwvwe{index + 1}") as LargeLotterySpellCardComp)?.InitData(spellCardId, true);
|
|
2671
|
+
`;
|
|
2672
|
+
const snippets = extractor.extractStrings(code);
|
|
2568
2673
|
{
|
|
2569
|
-
let targetSnippet = snippets[
|
|
2570
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"
|
|
2571
|
-
expect(targetSnippet.originalCode).toBe(`$"
|
|
2572
|
-
expect(targetSnippet.convertedCode).toBe(
|
|
2674
|
+
let targetSnippet = snippets[0];
|
|
2675
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"vwvwe{index + 1}"`));
|
|
2676
|
+
expect(targetSnippet.originalCode).toBe(`$"vwvwe{index + 1}"`);
|
|
2677
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("vwvwe{0}", index + 1)`);
|
|
2573
2678
|
expect(targetSnippet.literals).toEqual([
|
|
2574
|
-
|
|
2679
|
+
`vwvwe{0}`
|
|
2575
2680
|
]);
|
|
2576
|
-
expect(targetSnippet.isChanged).toBe(
|
|
2681
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2577
2682
|
}
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2683
|
+
expect(snippets.length).toBe(1);
|
|
2684
|
+
});
|
|
2685
|
+
|
|
2686
|
+
// 修正字符串表达式捕获范围
|
|
2687
|
+
test('should handle string expression capture range 2', () => {
|
|
2688
|
+
const code = `
|
|
2689
|
+
(GetChild($"brrr_{index + 1}") as LargeLotterySpellCardComp)?.InitData(spellCardId, true);
|
|
2690
|
+
`;
|
|
2581
2691
|
const snippets = extractor.extractStrings(code);
|
|
2582
|
-
{
|
|
2583
|
-
let targetSnippet = snippets[0];
|
|
2584
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
2585
|
-
expect(targetSnippet.originalCode).toBe(
|
|
2586
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
2692
|
+
{
|
|
2693
|
+
let targetSnippet = snippets[0];
|
|
2694
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"brrr_{index + 1}"`));
|
|
2695
|
+
expect(targetSnippet.originalCode).toBe(`$"brrr_{index + 1}"`);
|
|
2696
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("brrr_{0}", index + 1)`);
|
|
2587
2697
|
expect(targetSnippet.literals).toEqual([
|
|
2588
|
-
|
|
2698
|
+
`brrr_{0}`
|
|
2589
2699
|
]);
|
|
2590
2700
|
expect(targetSnippet.isChanged).toBe(true);
|
|
2591
2701
|
}
|
|
2592
|
-
|
|
2593
|
-
|
|
2702
|
+
expect(snippets.length).toBe(1);
|
|
2703
|
+
});
|
|
2704
|
+
|
|
2705
|
+
// 修正字符串表达式捕获范围
|
|
2706
|
+
test('should handle string expression capture range 3', () => {
|
|
2594
2707
|
const code = `
|
|
2595
|
-
|
|
2596
|
-
{
|
|
2597
|
-
public partial class SpellUpgradeDialog
|
|
2598
|
-
{
|
|
2599
|
-
private async void OnBtnUpgrade()
|
|
2600
|
-
{
|
|
2601
|
-
// new SpellCard_Action_UpgradeSpellCard(_symbolCard.Id) 被方法调用传参的 () 包裹, 因此已经构成了完整的对象创建表达式
|
|
2602
|
-
if (await this.GetModel<SpellCardModel>().DispatchAction(new SpellCard_Action_UpgradeSpellCard(_symbolCard.Id)))
|
|
2603
|
-
{
|
|
2604
|
-
//升级成功后刷新界面
|
|
2605
|
-
m_text_level.text = Tr.Format("{0}级", _symbolCard.Level);
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
}
|
|
2609
|
-
}
|
|
2708
|
+
(GetChild($"m_card_{index}") as LargeLotterySpellCardComp)?.PlayEff();
|
|
2610
2709
|
`;
|
|
2611
2710
|
const snippets = extractor.extractStrings(code);
|
|
2612
2711
|
{
|
|
2613
2712
|
let targetSnippet = snippets[0];
|
|
2614
|
-
|
|
2615
|
-
expect(targetSnippet.
|
|
2616
|
-
expect(targetSnippet.
|
|
2617
|
-
expect(targetSnippet.convertedCode).toBe(`Tr.Format("{0}级", _symbolCard.Level)`);
|
|
2713
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`$"m_card_{index}"`));
|
|
2714
|
+
expect(targetSnippet.originalCode).toBe(`$"m_card_{index}"`);
|
|
2715
|
+
expect(targetSnippet.convertedCode).toBe(`Tr.Format("m_card_{0}", index)`);
|
|
2618
2716
|
expect(targetSnippet.literals).toEqual([
|
|
2619
|
-
|
|
2717
|
+
`m_card_{0}`
|
|
2620
2718
|
]);
|
|
2621
|
-
expect(targetSnippet.isChanged).toBe(
|
|
2719
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2622
2720
|
}
|
|
2623
2721
|
expect(snippets.length).toBe(1);
|
|
2624
|
-
})
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2722
|
+
});
|
|
2723
|
+
|
|
2724
|
+
// 字符串表达式字面量直接为null时, 无需转换null
|
|
2725
|
+
test('should handle null 1', () => {
|
|
2726
|
+
const code = `m_text_notice.text = null;`;
|
|
2629
2727
|
const snippets = extractor.extractStrings(code);
|
|
2630
2728
|
{
|
|
2631
2729
|
let targetSnippet = snippets[0];
|
|
2632
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
2633
|
-
expect(targetSnippet.originalCode).toBe(
|
|
2634
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
2730
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`null`));
|
|
2731
|
+
expect(targetSnippet.originalCode).toBe(`null`);
|
|
2732
|
+
expect(targetSnippet.convertedCode).toBe(`null`);
|
|
2635
2733
|
expect(targetSnippet.literals).toEqual([
|
|
2636
|
-
`m_loader_dailyItem{0}`
|
|
2637
2734
|
]);
|
|
2638
|
-
expect(targetSnippet.isChanged).toBe(
|
|
2735
|
+
expect(targetSnippet.isChanged).toBe(false);
|
|
2639
2736
|
}
|
|
2640
2737
|
expect(snippets.length).toBe(1);
|
|
2641
|
-
})
|
|
2642
|
-
|
|
2738
|
+
});
|
|
2739
|
+
|
|
2740
|
+
// 字符串表达式字面量直接为null时, 无需转换null
|
|
2741
|
+
test('should handle null 2', () => {
|
|
2742
|
+
const code = `m_text_notice.wfefe = null;`;
|
|
2743
|
+
const snippets = extractor.extractStrings(code);
|
|
2744
|
+
expect(snippets.length).toBe(0);
|
|
2745
|
+
});
|
|
2746
|
+
|
|
2747
|
+
// 需要正确获取 `originalIndex`, `originalIndex` 的定义为 `originalIndex=code.indexOf(originalCode)`, 其中 `code` 表示原始代码, `originalCode` 表示匹配出的原始代码中的字符串表达式
|
|
2748
|
+
test('should handle calculate originalIndex', () => {
|
|
2643
2749
|
const code = `
|
|
2644
2750
|
namespace FaBao
|
|
2645
2751
|
{
|
|
@@ -2669,109 +2775,373 @@ namespace FaBao
|
|
|
2669
2775
|
]);
|
|
2670
2776
|
expect(targetSnippet.isChanged).toBe(false);
|
|
2671
2777
|
}
|
|
2672
|
-
})
|
|
2673
2778
|
});
|
|
2674
2779
|
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
const code =
|
|
2780
|
+
// 测试 `xxx.text = yyy;` 和 `m_btn_xxx.title = yyy;` 形式的赋值语句都需要支持中文, 包括字符串表达式中也要支持包含中文的情况
|
|
2781
|
+
test('should handle .text = assignments contains chinese', () => {
|
|
2782
|
+
const code = `
|
|
2783
|
+
为栓饭cxs12.text = 南方eflkj.d文件 + "完善ew";
|
|
2784
|
+
m_btn_为栓饭cxs12.title = bw尅kljekl.完善 + "栏栏nfc";
|
|
2785
|
+
`;
|
|
2678
2786
|
const snippets = extractor.extractStrings(code);
|
|
2787
|
+
{
|
|
2788
|
+
let snippet = snippets[0];
|
|
2789
|
+
expect(snippet.originalCode).toBe('南方eflkj.d文件 + "完善ew"');
|
|
2790
|
+
expect(snippet.convertedCode).toBe('南方eflkj.d文件.TR() + "完善ew".TR()');
|
|
2791
|
+
expect(snippet.literals).toEqual([
|
|
2792
|
+
'完善ew'
|
|
2793
|
+
]);
|
|
2794
|
+
}
|
|
2795
|
+
{
|
|
2796
|
+
let snippet = snippets[1];
|
|
2797
|
+
expect(snippet.originalCode).toBe('bw尅kljekl.完善 + "栏栏nfc"');
|
|
2798
|
+
expect(snippet.convertedCode).toBe('bw尅kljekl.完善.TR() + "栏栏nfc".TR()');
|
|
2799
|
+
expect(snippet.literals).toEqual([
|
|
2800
|
+
'栏栏nfc'
|
|
2801
|
+
]);
|
|
2802
|
+
}
|
|
2803
|
+
});
|
|
2679
2804
|
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2805
|
+
// 测试`m_btn_xxx.title = yyy;` 形式的赋值语句要和`xxx.text = yyy;`形式的赋值语句完全等同处理
|
|
2806
|
+
test('should handle m_btn_xxx.title = yyy assignments contains chinese', () => {
|
|
2807
|
+
const code = `
|
|
2808
|
+
switch (_roomData.RoomState)
|
|
2809
|
+
{
|
|
2810
|
+
case Data.Match.RoomState.IsDismiss:
|
|
2811
|
+
m_btn_join.title = "已解散";
|
|
2812
|
+
m_btn_join.enabled = false;
|
|
2813
|
+
grayed = true;
|
|
2814
|
+
break;
|
|
2815
|
+
case Data.Match.RoomState.Rejected:
|
|
2816
|
+
{
|
|
2817
|
+
m_btn_join.title = $"被拒绝{Kff}";
|
|
2818
|
+
m_btn_join.enabled = false;
|
|
2819
|
+
break;
|
|
2820
|
+
}
|
|
2821
|
+
case Data.Match.RoomState.OutOfDate:
|
|
2822
|
+
m_dd_join.text = "已到期";
|
|
2823
|
+
break;
|
|
2824
|
+
default:
|
|
2825
|
+
m_btn_join.title = "申请";
|
|
2826
|
+
m_btn_joi23n.title = $"申请{Kjf}";
|
|
2827
|
+
break;
|
|
2828
|
+
}
|
|
2829
|
+
`;
|
|
2688
2830
|
const snippets = extractor.extractStrings(code);
|
|
2689
2831
|
{
|
|
2690
|
-
|
|
2691
|
-
expect(snippet.originalCode).toBe('"
|
|
2692
|
-
expect(snippet.convertedCode).toBe('"
|
|
2693
|
-
expect(snippet.literals).toEqual([
|
|
2694
|
-
|
|
2832
|
+
let snippet = snippets[0];
|
|
2833
|
+
expect(snippet.originalCode).toBe('"已解散"');
|
|
2834
|
+
expect(snippet.convertedCode).toBe('"已解散".TR()');
|
|
2835
|
+
expect(snippet.literals).toEqual([
|
|
2836
|
+
'已解散'
|
|
2837
|
+
]);
|
|
2838
|
+
}
|
|
2839
|
+
{
|
|
2840
|
+
let snippet = snippets[1];
|
|
2841
|
+
expect(snippet.originalCode).toBe('$"被拒绝{Kff}"');
|
|
2842
|
+
expect(snippet.convertedCode).toBe('Tr.Format("被拒绝{0}", Kff)');
|
|
2843
|
+
expect(snippet.literals).toEqual([
|
|
2844
|
+
'被拒绝{0}'
|
|
2845
|
+
]);
|
|
2846
|
+
}
|
|
2847
|
+
{
|
|
2848
|
+
let snippet = snippets[2];
|
|
2849
|
+
expect(snippet.originalCode).toBe('"已到期"');
|
|
2850
|
+
expect(snippet.convertedCode).toBe('"已到期".TR()');
|
|
2851
|
+
expect(snippet.literals).toEqual([
|
|
2852
|
+
'已到期'
|
|
2853
|
+
]);
|
|
2854
|
+
}
|
|
2855
|
+
{
|
|
2856
|
+
let snippet = snippets[3];
|
|
2857
|
+
expect(snippet.originalCode).toBe('"申请"');
|
|
2858
|
+
expect(snippet.convertedCode).toBe('"申请".TR()');
|
|
2859
|
+
expect(snippet.literals).toEqual([
|
|
2860
|
+
'申请'
|
|
2861
|
+
]);
|
|
2695
2862
|
}
|
|
2696
2863
|
{
|
|
2864
|
+
let snippet = snippets[4];
|
|
2865
|
+
expect(snippet.originalCode).toBe('$"申请{Kjf}"');
|
|
2866
|
+
expect(snippet.convertedCode).toBe('Tr.Format("申请{0}", Kjf)');
|
|
2867
|
+
expect(snippet.literals).toEqual([
|
|
2868
|
+
'申请{0}'
|
|
2869
|
+
]);
|
|
2870
|
+
}
|
|
2871
|
+
});
|
|
2697
2872
|
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2873
|
+
// 测试三元表达式中的字符串表达式处理
|
|
2874
|
+
test('should handle thriple expression with string expression 1', () => {
|
|
2875
|
+
const code = `m_btn_confirm.title = isUsed ? "使用中" : "使用";`;
|
|
2876
|
+
const snippets = extractor.extractStrings(code);
|
|
2877
|
+
{
|
|
2878
|
+
let snippet = snippets[0];
|
|
2879
|
+
expect(snippet.originalCode).toBe('isUsed ? "使用中" : "使用"');
|
|
2880
|
+
expect(snippet.convertedCode).toBe('isUsed ? "使用中".TR() : "使用".TR()');
|
|
2881
|
+
expect(snippet.literals).toEqual([
|
|
2882
|
+
'使用中',
|
|
2883
|
+
'使用'
|
|
2884
|
+
]);
|
|
2703
2885
|
}
|
|
2704
|
-
})
|
|
2705
|
-
|
|
2706
|
-
|
|
2886
|
+
});
|
|
2887
|
+
|
|
2888
|
+
// 测试三元表达式中的字符串表达式处理
|
|
2889
|
+
test('should handle thriple expression with string expression 2', () => {
|
|
2890
|
+
const code = `wefe.text = isUsed ? "使用中" : "使用";`;
|
|
2707
2891
|
const snippets = extractor.extractStrings(code);
|
|
2892
|
+
{
|
|
2893
|
+
let snippet = snippets[0];
|
|
2894
|
+
expect(snippet.originalCode).toBe('isUsed ? "使用中" : "使用"');
|
|
2895
|
+
expect(snippet.convertedCode).toBe('isUsed ? "使用中".TR() : "使用".TR()');
|
|
2896
|
+
expect(snippet.literals).toEqual([
|
|
2897
|
+
'使用中',
|
|
2898
|
+
'使用'
|
|
2899
|
+
]);
|
|
2900
|
+
}
|
|
2901
|
+
});
|
|
2708
2902
|
|
|
2709
|
-
|
|
2710
|
-
|
|
2903
|
+
// 测试三元表达式中的字符串表达式处理
|
|
2904
|
+
test('should handle thriple expression with string expression 3', () => {
|
|
2905
|
+
const code = `wefetext = isUsed ? "使用中" : "使用";`;
|
|
2906
|
+
const snippets = extractor.extractStrings(code);
|
|
2907
|
+
{
|
|
2908
|
+
let snippet = snippets[0];
|
|
2909
|
+
expect(snippet.originalCode).toBe('isUsed ? "使用中" : "使用"');
|
|
2910
|
+
expect(snippet.convertedCode).toBe('isUsed ? "使用中" : "使用"');
|
|
2911
|
+
expect(snippet.literals).toEqual([
|
|
2912
|
+
'使用中',
|
|
2913
|
+
'使用'
|
|
2914
|
+
]);
|
|
2915
|
+
}
|
|
2916
|
+
});
|
|
2711
2917
|
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2918
|
+
// 测试三元表达式中的字符串表达式处理
|
|
2919
|
+
test('should handle thriple expression with string expression 4', () => {
|
|
2920
|
+
const code = `wefetext(isUsed ? "使用中" : "使用");`;
|
|
2921
|
+
const snippets = extractor.extractStrings(code);
|
|
2922
|
+
{
|
|
2923
|
+
let snippet = snippets[0];
|
|
2924
|
+
expect(snippet.originalCode).toBe('isUsed ? "使用中" : "使用"');
|
|
2925
|
+
expect(snippet.convertedCode).toBe('isUsed ? "使用中" : "使用"');
|
|
2926
|
+
expect(snippet.literals).toEqual([
|
|
2927
|
+
'使用中',
|
|
2928
|
+
'使用'
|
|
2929
|
+
]);
|
|
2930
|
+
}
|
|
2931
|
+
});
|
|
2717
2932
|
|
|
2718
|
-
|
|
2719
|
-
|
|
2933
|
+
// 测试if语句有花括号包围的单句表达式语句中的字符串表达式处理
|
|
2934
|
+
test('should handle assignment expression within if{}else{}', () => {
|
|
2720
2935
|
const code = `
|
|
2721
|
-
|
|
2722
|
-
{
|
|
2723
|
-
var iaaConfig = IAAConfigTable.GetConfigById((int)IAAId.境界失败_加速冷却);
|
|
2724
|
-
if (iaaConfig == null)
|
|
2936
|
+
if (_eventIdx < _table.MainDescription.Length)
|
|
2725
2937
|
{
|
|
2726
|
-
|
|
2938
|
+
m_text_desc.text = _table.MainDescription[_eventIdx];
|
|
2939
|
+
}
|
|
2940
|
+
else
|
|
2941
|
+
{
|
|
2942
|
+
m_text_desc.text = _table.MainDescription[0];
|
|
2727
2943
|
}
|
|
2728
|
-
|
|
2729
|
-
string des = $"观看视频后\n等待时间减少{iaaConfig.EffectValue / 60}分钟";
|
|
2730
|
-
this.GetModel<IAAModel>().ShowAdWithDialog(IAAId.境界失败_加速冷却, "加速时间", des, null);
|
|
2731
|
-
}
|
|
2732
2944
|
`;
|
|
2733
2945
|
const snippets = extractor.extractStrings(code);
|
|
2946
|
+
{
|
|
2947
|
+
let targetSnippet = snippets[0];
|
|
2948
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[_eventIdx]`));
|
|
2949
|
+
expect(targetSnippet.originalCode).toBe(`_table.MainDescription[_eventIdx]`);
|
|
2950
|
+
expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[_eventIdx].TR()`);
|
|
2951
|
+
expect(targetSnippet.literals).toEqual([
|
|
2952
|
+
]);
|
|
2953
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2954
|
+
}
|
|
2734
2955
|
{
|
|
2735
2956
|
let targetSnippet = snippets[1];
|
|
2736
|
-
|
|
2737
|
-
expect(targetSnippet.
|
|
2738
|
-
expect(targetSnippet.
|
|
2739
|
-
expect(targetSnippet.convertedCode).toBe(`"加速时间"`);
|
|
2957
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[0]`));
|
|
2958
|
+
expect(targetSnippet.originalCode).toBe(`_table.MainDescription[0]`);
|
|
2959
|
+
expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[0].TR()`);
|
|
2740
2960
|
expect(targetSnippet.literals).toEqual([
|
|
2741
|
-
'加速时间'
|
|
2742
2961
|
]);
|
|
2743
|
-
expect(targetSnippet.isChanged).toBe(
|
|
2962
|
+
expect(targetSnippet.isChanged).toBe(true);
|
|
2744
2963
|
}
|
|
2964
|
+
expect(snippets.length).toBe(2);
|
|
2745
2965
|
})
|
|
2746
|
-
|
|
2966
|
+
|
|
2967
|
+
// 测试if语句无花括号包围的单句表达式语句中的字符串表达式处理
|
|
2968
|
+
test('should handle assignment expression within if-else-end', () => {
|
|
2747
2969
|
const code = `
|
|
2748
|
-
|
|
2970
|
+
if (_eventIdx < _table.MainDescription.Length)
|
|
2971
|
+
m_text_desc.text = _table.MainDescription[_eventIdx];
|
|
2972
|
+
else
|
|
2973
|
+
m_text_desc.text = _table.MainDescription[0];
|
|
2749
2974
|
`;
|
|
2750
2975
|
const snippets = extractor.extractStrings(code);
|
|
2751
2976
|
{
|
|
2752
2977
|
let targetSnippet = snippets[0];
|
|
2753
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
2754
|
-
expect(targetSnippet.originalCode).toBe(
|
|
2755
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
2978
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[_eventIdx]`));
|
|
2979
|
+
expect(targetSnippet.originalCode).toBe(`_table.MainDescription[_eventIdx]`);
|
|
2980
|
+
expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[_eventIdx].TR()`);
|
|
2756
2981
|
expect(targetSnippet.literals).toEqual([
|
|
2757
|
-
`m_text_dailyCount{0}`
|
|
2758
2982
|
]);
|
|
2759
2983
|
expect(targetSnippet.isChanged).toBe(true);
|
|
2760
2984
|
}
|
|
2761
2985
|
{
|
|
2762
2986
|
let targetSnippet = snippets[1];
|
|
2763
|
-
expect(targetSnippet.originalIndex).toBe(code.indexOf(
|
|
2764
|
-
expect(targetSnippet.originalCode).toBe(
|
|
2765
|
-
expect(targetSnippet.convertedCode).toBe(`
|
|
2987
|
+
expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[0]`));
|
|
2988
|
+
expect(targetSnippet.originalCode).toBe(`_table.MainDescription[0]`);
|
|
2989
|
+
expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[0].TR()`);
|
|
2766
2990
|
expect(targetSnippet.literals).toEqual([
|
|
2767
|
-
`x{0}`
|
|
2768
2991
|
]);
|
|
2769
2992
|
expect(targetSnippet.isChanged).toBe(true);
|
|
2770
2993
|
}
|
|
2771
2994
|
expect(snippets.length).toBe(2);
|
|
2772
2995
|
})
|
|
2773
|
-
});
|
|
2774
2996
|
|
|
2775
|
-
|
|
2997
|
+
// // 测试if语句无花括号包围的单句表达式语句中的字符串表达式处理
|
|
2998
|
+
// test('should handle assignment expression within if-else-end', () => {
|
|
2999
|
+
// const code = `
|
|
3000
|
+
// private void RefreshRedDot()
|
|
3001
|
+
// {
|
|
3002
|
+
// m_redDot.visible = _data.NeedShowRedDot();
|
|
3003
|
+
// }
|
|
3004
|
+
|
|
3005
|
+
// private void OnSelfClick()
|
|
3006
|
+
// {
|
|
3007
|
+
// this.GetSystem<AudioSys>().PlayAudioByName(AudioName.SoundUI_Button);
|
|
3008
|
+
|
|
3009
|
+
// if (!_data.IsOpen)
|
|
3010
|
+
// {
|
|
3011
|
+
// string tip = _data.Config.LockTip;
|
|
3012
|
+
// if (_data.Config.TaskIds != null && _data.Config.TaskIds.Count > 0)
|
|
3013
|
+
// {
|
|
3014
|
+
// int taskId = App.Instance.GetModel<MissionModel>().CurGuideMissionConfig.Id;
|
|
3015
|
+
// int remainingTaskCount = _data.Config.TaskIds[0] - taskId + 1;
|
|
3016
|
+
// remainingTaskCount = Mathf.Max(0, remainingTaskCount);
|
|
3017
|
+
// tip = string.Format(_data.Config.LockTip, remainingTaskCount);
|
|
3018
|
+
// }
|
|
3019
|
+
|
|
3020
|
+
// Toast.Info(tip);
|
|
3021
|
+
// return;
|
|
3022
|
+
// }
|
|
3023
|
+
|
|
3024
|
+
|
|
3025
|
+
// `;
|
|
3026
|
+
|
|
3027
|
+
// const snippets = extractor.extractStrings(code);
|
|
3028
|
+
// {
|
|
3029
|
+
// let targetSnippet = snippets[0];
|
|
3030
|
+
// expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[_eventIdx]`));
|
|
3031
|
+
// expect(targetSnippet.originalCode).toBe(`_table.MainDescription[_eventIdx]`);
|
|
3032
|
+
// expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[_eventIdx].TR()`);
|
|
3033
|
+
// expect(targetSnippet.literals).toEqual([
|
|
3034
|
+
// ]);
|
|
3035
|
+
// expect(targetSnippet.isChanged).toBe(true);
|
|
3036
|
+
// }
|
|
3037
|
+
// {
|
|
3038
|
+
// let targetSnippet = snippets[1];
|
|
3039
|
+
// expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[0]`));
|
|
3040
|
+
// expect(targetSnippet.originalCode).toBe(`_table.MainDescription[0]`);
|
|
3041
|
+
// expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[0].TR()`);
|
|
3042
|
+
// expect(targetSnippet.literals).toEqual([
|
|
3043
|
+
// ]);
|
|
3044
|
+
// expect(targetSnippet.isChanged).toBe(true);
|
|
3045
|
+
// }
|
|
3046
|
+
// expect(snippets.length).toBe(2);
|
|
3047
|
+
// })
|
|
3048
|
+
|
|
3049
|
+
// // 测试if语句无花括号包围的单句表达式语句中的字符串表达式处理
|
|
3050
|
+
// test('should handle assignment expression within if-else-end', () => {
|
|
3051
|
+
// const code = `
|
|
3052
|
+
// protected override void OnCreate()
|
|
3053
|
+
// {
|
|
3054
|
+
// base.OnCreate();
|
|
3055
|
+
// }
|
|
3056
|
+
|
|
3057
|
+
// protected override void OnShow(object param)
|
|
3058
|
+
// {
|
|
3059
|
+
// base.OnShow(param);
|
|
3060
|
+
|
|
3061
|
+
// var mailContent = (MailContentDialogParam)param;
|
|
3062
|
+
// if (mailContent == null) return;
|
|
3063
|
+
|
|
3064
|
+
// var mailData = this.GetModel<MailModel>().GetMail(mailContent.MailId);
|
|
3065
|
+
// if (mailData == null) return;
|
|
3066
|
+
|
|
3067
|
+
// _mailId = mailData.MailId;
|
|
3068
|
+
// m_text_title.text = mailData.Title.TR();
|
|
3069
|
+
// m_text_name.text = $"道友如晤:".TR();
|
|
3070
|
+
// m_text_sender.text = Tr.Format("{0}稽首", mailData.Name);
|
|
3071
|
+
// //转换时区
|
|
3072
|
+
// // var dateTimeOffset = TimeZoneInfo.ConvertTime(DateTimeOffset.FromUnixTimeSeconds(mailData.ReceiveTime), TimeZoneInfo.Local);
|
|
3073
|
+
// m_text_time.text = Date.ConvertTimestampToTimeString(mailData.ReceiveTime, "yyyy年M月d日 HH:mm").TR();
|
|
3074
|
+
// m_scroll_content.title = mailData.Content;
|
|
3075
|
+
|
|
3076
|
+
// `;
|
|
3077
|
+
|
|
3078
|
+
// const snippets = extractor.extractStrings(code);
|
|
3079
|
+
// {
|
|
3080
|
+
// let targetSnippet = snippets[0];
|
|
3081
|
+
// expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[_eventIdx]`));
|
|
3082
|
+
// expect(targetSnippet.originalCode).toBe(`_table.MainDescription[_eventIdx]`);
|
|
3083
|
+
// expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[_eventIdx].TR()`);
|
|
3084
|
+
// expect(targetSnippet.literals).toEqual([
|
|
3085
|
+
// ]);
|
|
3086
|
+
// expect(targetSnippet.isChanged).toBe(true);
|
|
3087
|
+
// }
|
|
3088
|
+
// {
|
|
3089
|
+
// let targetSnippet = snippets[1];
|
|
3090
|
+
// expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[0]`));
|
|
3091
|
+
// expect(targetSnippet.originalCode).toBe(`_table.MainDescription[0]`);
|
|
3092
|
+
// expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[0].TR()`);
|
|
3093
|
+
// expect(targetSnippet.literals).toEqual([
|
|
3094
|
+
// ]);
|
|
3095
|
+
// expect(targetSnippet.isChanged).toBe(true);
|
|
3096
|
+
// }
|
|
3097
|
+
// expect(snippets.length).toBe(2);
|
|
3098
|
+
// })
|
|
3099
|
+
|
|
3100
|
+
// // 测试if语句无花括号包围的单句表达式语句中的字符串表达式处理
|
|
3101
|
+
// test('should handle assignment expression within if-else-end', () => {
|
|
3102
|
+
// const code = `
|
|
3103
|
+
// public void BindData(MailData mailData)
|
|
3104
|
+
// {
|
|
3105
|
+
// if (mailData == null) return;
|
|
3106
|
+
// _mailData = mailData;
|
|
3107
|
+
// //状态
|
|
3108
|
+
// m_hasRead.selectedIndex = _mailData.HasRead ? (int)HasRead.True : (int)HasRead.False;
|
|
3109
|
+
// m_hasFetch.selectedIndex = mailData.Rewards.Count > 0 ? (int)HasFetch.True : (int)HasFetch.False;
|
|
3110
|
+
|
|
3111
|
+
// m_text_title.text = _mailData.Title.TR();
|
|
3112
|
+
// m_text_subTitle.text = _mailData.SubTitle.TR();
|
|
3113
|
+
// //显示时间
|
|
3114
|
+
// long interval = DateTimeOffset.Now.ToUnixTimeSeconds() - mailData.ReceiveTime;
|
|
3115
|
+
// if (interval <= 0) interval = 1;
|
|
3116
|
+
// if (interval < 60) m_text_time.text = "现在";
|
|
3117
|
+
// else if (interval < 3600) m_text_time.text = $"{interval / 60}分钟前";
|
|
3118
|
+
// else if (interval < 86400) m_text_time.text = $"{interval / 3600}小时前";
|
|
3119
|
+
// else if (interval < 2592000) m_text_time.text = $"{interval / 86400}天前";
|
|
3120
|
+
// else if (interval < 31104000) m_text_time.text = $"{interval / 2592000}月前";
|
|
3121
|
+
// else m_text_time.text = Tr.Format("{0}年前", interval / 31104000);
|
|
3122
|
+
// }
|
|
3123
|
+
// `;
|
|
3124
|
+
|
|
3125
|
+
// const snippets = extractor.extractStrings(code);
|
|
3126
|
+
// {
|
|
3127
|
+
// let targetSnippet = snippets[0];
|
|
3128
|
+
// expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[_eventIdx]`));
|
|
3129
|
+
// expect(targetSnippet.originalCode).toBe(`_table.MainDescription[_eventIdx]`);
|
|
3130
|
+
// expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[_eventIdx].TR()`);
|
|
3131
|
+
// expect(targetSnippet.literals).toEqual([
|
|
3132
|
+
// ]);
|
|
3133
|
+
// expect(targetSnippet.isChanged).toBe(true);
|
|
3134
|
+
// }
|
|
3135
|
+
// {
|
|
3136
|
+
// let targetSnippet = snippets[1];
|
|
3137
|
+
// expect(targetSnippet.originalIndex).toBe(code.indexOf(`_table.MainDescription[0]`));
|
|
3138
|
+
// expect(targetSnippet.originalCode).toBe(`_table.MainDescription[0]`);
|
|
3139
|
+
// expect(targetSnippet.convertedCode).toBe(`_table.MainDescription[0].TR()`);
|
|
3140
|
+
// expect(targetSnippet.literals).toEqual([
|
|
3141
|
+
// ]);
|
|
3142
|
+
// expect(targetSnippet.isChanged).toBe(true);
|
|
3143
|
+
// }
|
|
3144
|
+
// expect(snippets.length).toBe(2);
|
|
3145
|
+
// })
|
|
2776
3146
|
|
|
2777
3147
|
});
|