|
1 | 1 | import { expect, test, vi } from 'vitest' |
2 | | -import { fileReferenceToString, getAnswerPartFromAssistantMessage, groupMessageIntoSteps } from './utils' |
| 2 | +import { fileReferenceToString, getAnswerPartFromAssistantMessage, groupMessageIntoSteps, repairCitations } from './utils' |
3 | 3 | import { FILE_REFERENCE_REGEX, ANSWER_TAG } from './constants'; |
4 | 4 | import { SBChatMessage, SBChatMessagePart } from './types'; |
5 | 5 |
|
@@ -238,3 +238,88 @@ test('getAnswerPartFromAssistantMessage returns undefined when streaming and no |
238 | 238 |
|
239 | 239 | expect(result).toBeUndefined(); |
240 | 240 | }); |
| 241 | + |
| 242 | +test('repairCitations fixes missing colon after @file', () => { |
| 243 | + const input = 'See the function in @file{auth.ts} for details.'; |
| 244 | + const expected = 'See the function in @file:{auth.ts} for details.'; |
| 245 | + expect(repairCitations(input)).toBe(expected); |
| 246 | +}); |
| 247 | + |
| 248 | +test('repairCitations fixes missing colon with range', () => { |
| 249 | + const input = 'Check @file{config.ts:15-20} for the configuration.'; |
| 250 | + const expected = 'Check @file:{config.ts:15-20} for the configuration.'; |
| 251 | + expect(repairCitations(input)).toBe(expected); |
| 252 | +}); |
| 253 | + |
| 254 | +test('repairCitations fixes missing braces around filename', () => { |
| 255 | + const input = 'The logic is in @file:utils.js and handles validation.'; |
| 256 | + const expected = 'The logic is in @file:{utils.js} and handles validation.'; |
| 257 | + expect(repairCitations(input)).toBe(expected); |
| 258 | +}); |
| 259 | + |
| 260 | +test('repairCitations fixes missing braces with path', () => { |
| 261 | + const input = 'Look at @file:src/components/Button.tsx for the component.'; |
| 262 | + const expected = 'Look at @file:{src/components/Button.tsx} for the component.'; |
| 263 | + expect(repairCitations(input)).toBe(expected); |
| 264 | +}); |
| 265 | + |
| 266 | +test('repairCitations removes multiple ranges keeping only first', () => { |
| 267 | + const input = 'See @file:{service.ts:10-15,20-25,30-35} for implementation.'; |
| 268 | + const expected = 'See @file:{service.ts:10-15} for implementation.'; |
| 269 | + expect(repairCitations(input)).toBe(expected); |
| 270 | +}); |
| 271 | + |
| 272 | +test('repairCitations fixes malformed triple number ranges', () => { |
| 273 | + const input = 'Check @file:{handler.ts:5-10-15} for the logic.'; |
| 274 | + const expected = 'Check @file:{handler.ts:5-10} for the logic.'; |
| 275 | + expect(repairCitations(input)).toBe(expected); |
| 276 | +}); |
| 277 | + |
| 278 | +test('repairCitations handles multiple citations in same text', () => { |
| 279 | + const input = 'See @file{auth.ts} and @file:config.js for setup details.'; |
| 280 | + const expected = 'See @file:{auth.ts} and @file:{config.js} for setup details.'; |
| 281 | + expect(repairCitations(input)).toBe(expected); |
| 282 | +}); |
| 283 | + |
| 284 | +test('repairCitations leaves correctly formatted citations unchanged', () => { |
| 285 | + const input = 'The function @file:{utils.ts:42-50} handles validation correctly.'; |
| 286 | + expect(repairCitations(input)).toBe(input); |
| 287 | +}); |
| 288 | + |
| 289 | +test('repairCitations handles edge cases with spaces and punctuation', () => { |
| 290 | + const input = 'Functions like @file:helper.ts, @file{main.js}, and @file:{app.ts:1-5,10-15} work.'; |
| 291 | + const expected = 'Functions like @file:{helper.ts}, @file:{main.js}, and @file:{app.ts:1-5} work.'; |
| 292 | + expect(repairCitations(input)).toBe(expected); |
| 293 | +}); |
| 294 | + |
| 295 | +test('repairCitations returns empty string unchanged', () => { |
| 296 | + expect(repairCitations('')).toBe(''); |
| 297 | +}); |
| 298 | + |
| 299 | +test('repairCitations returns text without citations unchanged', () => { |
| 300 | + const input = 'This is just regular text without any file references.'; |
| 301 | + expect(repairCitations(input)).toBe(input); |
| 302 | +}); |
| 303 | + |
| 304 | +test('repairCitations handles complex file paths correctly', () => { |
| 305 | + const input = 'Check @file:src/components/ui/Button/index.tsx for implementation.'; |
| 306 | + const expected = 'Check @file:{src/components/ui/Button/index.tsx} for implementation.'; |
| 307 | + expect(repairCitations(input)).toBe(expected); |
| 308 | +}); |
| 309 | + |
| 310 | +test('repairCitations handles files with numbers and special characters', () => { |
| 311 | + const input = 'See @file{utils-v2.0.1.ts} and @file:config_2024.json for setup.'; |
| 312 | + const expected = 'See @file:{utils-v2.0.1.ts} and @file:{config_2024.json} for setup.'; |
| 313 | + expect(repairCitations(input)).toBe(expected); |
| 314 | +}); |
| 315 | + |
| 316 | +test('repairCitations handles citation at end of sentence', () => { |
| 317 | + const input = 'The implementation is in @file:helper.ts.'; |
| 318 | + const expected = 'The implementation is in @file:{helper.ts}.'; |
| 319 | + expect(repairCitations(input)).toBe(expected); |
| 320 | +}); |
| 321 | + |
| 322 | +test('repairCitations preserves already correct citations with ranges', () => { |
| 323 | + const input = 'The function @file:{utils.ts:10-20} and variable @file:{config.js:5} work correctly.'; |
| 324 | + expect(repairCitations(input)).toBe(input); |
| 325 | +}); |
0 commit comments