|
1 | 1 | import { describe, it, expect } from 'vitest'; |
2 | | -import { parseBlanks } from './parse-blanks'; |
| 2 | +import { |
| 3 | + parseBlanks, |
| 4 | + parseHanziPinyinPairs, |
| 5 | + parseAnswer |
| 6 | +} from './parse-blanks'; |
3 | 7 |
|
4 | 8 | describe('parseBlanks', () => { |
5 | 9 | it('handles strings without blanks', () => { |
@@ -129,4 +133,221 @@ describe('parseBlanks', () => { |
129 | 133 | expect(() => parseBlanks('<p>hello BLANK!</p>hello BLANK!')).toThrow(); |
130 | 134 | expect(() => parseBlanks('hello BLANK!<p>hello</p>')).toThrow(); |
131 | 135 | }); |
| 136 | + |
| 137 | + it('handles Chinese with single BLANK', () => { |
| 138 | + expect( |
| 139 | + parseBlanks('<p>BLANK<ruby>好<rp>(</rp><rt>hǎo</rt><rp>)</rp></ruby></p>') |
| 140 | + ).toEqual([ |
| 141 | + [ |
| 142 | + { type: 'blank', value: 0 }, |
| 143 | + { |
| 144 | + type: 'hanzi-pinyin', |
| 145 | + value: { hanzi: '好', pinyin: 'hǎo' } |
| 146 | + } |
| 147 | + ] |
| 148 | + ]); |
| 149 | + }); |
| 150 | + |
| 151 | + it('handles Chinese without pinyin', () => { |
| 152 | + expect(parseBlanks('<p>你BLANK好</p>')).toEqual([ |
| 153 | + [ |
| 154 | + { type: 'text', value: '你' }, |
| 155 | + { type: 'blank', value: 0 }, |
| 156 | + { type: 'text', value: '好' } |
| 157 | + ] |
| 158 | + ]); |
| 159 | + }); |
| 160 | + |
| 161 | + it('handles Chinese with multiple BLANKs', () => { |
| 162 | + expect( |
| 163 | + parseBlanks( |
| 164 | + '<p>BLANK<ruby>好<rp>(</rp><rt>hǎo</rt><rp>)</rp></ruby>,BLANK<ruby>是王华<rp>(</rp><rt>shì Wang Hua</rt><rp>)</rp></ruby></p>' |
| 165 | + ) |
| 166 | + ).toEqual([ |
| 167 | + [ |
| 168 | + { type: 'blank', value: 0 }, |
| 169 | + { |
| 170 | + type: 'hanzi-pinyin', |
| 171 | + value: { hanzi: '好', pinyin: 'hǎo' } |
| 172 | + }, |
| 173 | + { type: 'text', value: ',' }, |
| 174 | + { type: 'blank', value: 1 }, |
| 175 | + { |
| 176 | + type: 'hanzi-pinyin', |
| 177 | + value: { hanzi: '是王华', pinyin: 'shì Wang Hua' } |
| 178 | + } |
| 179 | + ] |
| 180 | + ]); |
| 181 | + }); |
| 182 | + |
| 183 | + it('handles Chinese with multiple adjacent BLANKs', () => { |
| 184 | + expect( |
| 185 | + parseBlanks( |
| 186 | + '<p>BLANK BLANK<ruby>好<rp>(</rp><rt>hǎo</rt><rp>)</rp></ruby></p>' |
| 187 | + ) |
| 188 | + ).toEqual([ |
| 189 | + [ |
| 190 | + { type: 'blank', value: 0 }, |
| 191 | + { type: 'text', value: ' ' }, |
| 192 | + { type: 'blank', value: 1 }, |
| 193 | + { |
| 194 | + type: 'hanzi-pinyin', |
| 195 | + value: { hanzi: '好', pinyin: 'hǎo' } |
| 196 | + } |
| 197 | + ] |
| 198 | + ]); |
| 199 | + }); |
| 200 | + |
| 201 | + it('handles Chinese with BLANK at the end', () => { |
| 202 | + expect( |
| 203 | + parseBlanks( |
| 204 | + '<p><ruby>你好<rp>(</rp><rt>nǐ hǎo</rt><rp>)</rp></ruby>BLANK</p>' |
| 205 | + ) |
| 206 | + ).toEqual([ |
| 207 | + [ |
| 208 | + { |
| 209 | + type: 'hanzi-pinyin', |
| 210 | + value: { hanzi: '你好', pinyin: 'nǐ hǎo' } |
| 211 | + }, |
| 212 | + { type: 'blank', value: 0 } |
| 213 | + ] |
| 214 | + ]); |
| 215 | + }); |
| 216 | + |
| 217 | + it('handles Chinese with spaces around BLANK', () => { |
| 218 | + expect( |
| 219 | + parseBlanks( |
| 220 | + '<p><ruby>你<rp>(</rp><rt>nǐ</rt><rp>)</rp></ruby> BLANK <ruby>我<rp>(</rp><rt>wǒ</rt><rp>)</rp></ruby></p>' |
| 221 | + ) |
| 222 | + ).toEqual([ |
| 223 | + [ |
| 224 | + { |
| 225 | + type: 'hanzi-pinyin', |
| 226 | + value: { hanzi: '你', pinyin: 'nǐ' } |
| 227 | + }, |
| 228 | + { type: 'text', value: ' ' }, |
| 229 | + { type: 'blank', value: 0 }, |
| 230 | + { type: 'text', value: ' ' }, |
| 231 | + { |
| 232 | + type: 'hanzi-pinyin', |
| 233 | + value: { hanzi: '我', pinyin: 'wǒ' } |
| 234 | + } |
| 235 | + ] |
| 236 | + ]); |
| 237 | + }); |
| 238 | + |
| 239 | + it('handles Latin text adjacent to BLANK', () => { |
| 240 | + expect( |
| 241 | + parseBlanks( |
| 242 | + '<p><ruby>我<rp>(</rp><rt>wǒ</rt><rp>)</rp></ruby> BLANK UI <ruby>设计师<rp>(</rp><rt>shè jì shī</rt><rp>)</rp></ruby> 。</p>' |
| 243 | + ) |
| 244 | + ).toEqual([ |
| 245 | + [ |
| 246 | + { |
| 247 | + type: 'hanzi-pinyin', |
| 248 | + value: { hanzi: '我', pinyin: 'wǒ' } |
| 249 | + }, |
| 250 | + { type: 'text', value: ' ' }, |
| 251 | + { type: 'blank', value: 0 }, |
| 252 | + { type: 'text', value: ' UI ' }, |
| 253 | + { |
| 254 | + type: 'hanzi-pinyin', |
| 255 | + value: { hanzi: '设计师', pinyin: 'shè jì shī' } |
| 256 | + }, |
| 257 | + { type: 'text', value: ' 。' } |
| 258 | + ] |
| 259 | + ]); |
| 260 | + }); |
| 261 | + |
| 262 | + it('handles Chinese with multiple separate groups', () => { |
| 263 | + expect( |
| 264 | + parseBlanks( |
| 265 | + '<p>BLANK<ruby>好<rp>(</rp><rt>hǎo</rt><rp>)</rp></ruby>,<ruby>我是王华<rp>(</rp><rt>wǒ shì Wang Hua</rt><rp>)</rp></ruby>,<ruby>请问你<rp>(</rp><rt>qǐng wèn nǐ</rt><rp>)</rp></ruby>BLANK<ruby>什么名字<rp>(</rp><rt>shén me míng zi</rt><rp>)</rp></ruby>?</p>' |
| 266 | + ) |
| 267 | + ).toEqual([ |
| 268 | + [ |
| 269 | + { type: 'blank', value: 0 }, |
| 270 | + { |
| 271 | + type: 'hanzi-pinyin', |
| 272 | + value: { hanzi: '好', pinyin: 'hǎo' } |
| 273 | + }, |
| 274 | + { type: 'text', value: ',' }, |
| 275 | + { |
| 276 | + type: 'hanzi-pinyin', |
| 277 | + value: { hanzi: '我是王华', pinyin: 'wǒ shì Wang Hua' } |
| 278 | + }, |
| 279 | + { type: 'text', value: ',' }, |
| 280 | + { |
| 281 | + type: 'hanzi-pinyin', |
| 282 | + value: { hanzi: '请问你', pinyin: 'qǐng wèn nǐ' } |
| 283 | + }, |
| 284 | + { type: 'blank', value: 1 }, |
| 285 | + { |
| 286 | + type: 'hanzi-pinyin', |
| 287 | + value: { hanzi: '什么名字', pinyin: 'shén me míng zi' } |
| 288 | + }, |
| 289 | + { type: 'text', value: '?' } |
| 290 | + ] |
| 291 | + ]); |
| 292 | + }); |
| 293 | + |
| 294 | + it('handles Chinese ruby with trailing punctuation', () => { |
| 295 | + expect( |
| 296 | + parseBlanks( |
| 297 | + '<p><ruby>你是刘明吗<rp>(</rp><rt>nǐ shì Liu Ming ma</rt><rp>)</rp></ruby>?</p>' |
| 298 | + ) |
| 299 | + ).toEqual([ |
| 300 | + [ |
| 301 | + { |
| 302 | + type: 'hanzi-pinyin', |
| 303 | + value: { hanzi: '你是刘明吗', pinyin: 'nǐ shì Liu Ming ma' } |
| 304 | + }, |
| 305 | + { type: 'text', value: '?' } |
| 306 | + ] |
| 307 | + ]); |
| 308 | + }); |
| 309 | +}); |
| 310 | + |
| 311 | +describe('parseHanziPinyinPairs', () => { |
| 312 | + it('parseHanziPinyinPairs returns array with one pair for well-formed input', () => { |
| 313 | + const result = parseHanziPinyinPairs('你好 (nǐ hǎo)'); |
| 314 | + expect(result).toHaveLength(1); |
| 315 | + expect(result[0]).toEqual({ |
| 316 | + hanzi: '你好', |
| 317 | + pinyin: 'nǐ hǎo' |
| 318 | + }); |
| 319 | + }); |
| 320 | + |
| 321 | + it('parseHanziPinyinPairs handles parentheses without a space', () => { |
| 322 | + const result = parseHanziPinyinPairs('你好(nǐ hǎo)'); |
| 323 | + expect(result).toHaveLength(1); |
| 324 | + expect(result[0]).toEqual({ |
| 325 | + hanzi: '你好', |
| 326 | + pinyin: 'nǐ hǎo' |
| 327 | + }); |
| 328 | + }); |
| 329 | + |
| 330 | + it('parseHanziPinyinPairs returns empty array for non-matching input', () => { |
| 331 | + expect(parseHanziPinyinPairs('hello')).toEqual([]); |
| 332 | + }); |
| 333 | + |
| 334 | + it('parseAnswer returns parsed object when pattern matches', () => { |
| 335 | + expect(parseAnswer('你好 (nǐ hǎo)')).toEqual({ |
| 336 | + hanzi: '你好', |
| 337 | + pinyin: 'nǐ hǎo' |
| 338 | + }); |
| 339 | + }); |
| 340 | +}); |
| 341 | + |
| 342 | +describe('parseAnswer', () => { |
| 343 | + it('parseAnswer returns hanzi-pinyin string when pattern matches', () => { |
| 344 | + expect(parseAnswer('你好(nǐ hǎo)')).toEqual({ |
| 345 | + hanzi: '你好', |
| 346 | + pinyin: 'nǐ hǎo' |
| 347 | + }); |
| 348 | + }); |
| 349 | + |
| 350 | + it('parseAnswer returns original string when pattern does not match', () => { |
| 351 | + expect(parseAnswer('just some text')).toBe('just some text'); |
| 352 | + }); |
132 | 353 | }); |
0 commit comments