char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Aleksander Grygierui: Linting & Formatting scripts (#26819)92d1bb0c9

char/aliceai-t5-moe
12.0 KiB421 linesraw
1import { AttachmentType } from '$lib/enums';
2import {
3	formatMessageForClipboard,
4	hasClipboardAttachments,
5	parseClipboardContent
6} from '$lib/utils/clipboard';
7import { describe, expect, it } from 'vitest';
8
9describe('formatMessageForClipboard', () => {
10	it('returns plain content when no extras', () => {
11		const result = formatMessageForClipboard('Hello world', undefined);
12
13		expect(result).toBe('Hello world');
14	});
15
16	it('returns plain content when extras is empty array', () => {
17		const result = formatMessageForClipboard('Hello world', []);
18
19		expect(result).toBe('Hello world');
20	});
21
22	it('handles empty string content', () => {
23		const result = formatMessageForClipboard('', undefined);
24
25		expect(result).toBe('');
26	});
27
28	it('returns plain content when extras has only non-text attachments', () => {
29		const extras = [
30			{
31				base64Url: 'data:image/png;base64,...',
32				name: 'image.png',
33				type: AttachmentType.IMAGE as const
34			}
35		];
36		const result = formatMessageForClipboard('Hello world', extras);
37
38		expect(result).toBe('Hello world');
39	});
40
41	it('filters non-text attachments and keeps only text ones', () => {
42		const extras = [
43			{
44				base64Url: 'data:image/png;base64,...',
45				name: 'image.png',
46				type: AttachmentType.IMAGE as const
47			},
48			{
49				content: 'Text content',
50				name: 'file.txt',
51				type: AttachmentType.TEXT as const
52			},
53			{
54				base64Data: 'data:application/pdf;base64,...',
55				content: 'PDF content',
56				name: 'doc.pdf',
57				processedAsImages: false,
58				type: AttachmentType.PDF as const
59			}
60		];
61		const result = formatMessageForClipboard('Hello', extras);
62
63		expect(result).toContain('"file.txt"');
64		expect(result).not.toContain('image.png');
65		expect(result).not.toContain('doc.pdf');
66	});
67
68	it('formats message with text attachments', () => {
69		const extras = [
70			{
71				content: 'File 1 content',
72				name: 'file1.txt',
73				type: AttachmentType.TEXT as const
74			},
75			{
76				content: 'File 2 content',
77				name: 'file2.txt',
78				type: AttachmentType.TEXT as const
79			}
80		];
81		const result = formatMessageForClipboard('Hello world', extras);
82
83		expect(result).toContain('"Hello world"');
84		expect(result).toContain('"type": "TEXT"');
85		expect(result).toContain('"name": "file1.txt"');
86		expect(result).toContain('"content": "File 1 content"');
87		expect(result).toContain('"name": "file2.txt"');
88	});
89
90	it('handles content with quotes and special characters', () => {
91		const content = 'Hello "world" with\nnewline';
92		const extras = [
93			{
94				content: 'Test content',
95				name: 'test.txt',
96				type: AttachmentType.TEXT as const
97			}
98		];
99		const result = formatMessageForClipboard(content, extras);
100
101		// Should be valid JSON
102		expect(result.startsWith('"')).toBe(true);
103		// The content should be properly escaped
104		const parsed = JSON.parse(result.split('\n')[0]);
105
106		expect(parsed).toBe(content);
107	});
108
109	it('converts legacy context type to TEXT type', () => {
110		const extras = [
111			{
112				content: 'Legacy content',
113				name: 'legacy.txt',
114				type: AttachmentType.LEGACY_CONTEXT as const
115			}
116		];
117		const result = formatMessageForClipboard('Hello', extras);
118
119		expect(result).toContain('"type": "TEXT"');
120		expect(result).not.toContain('"context"');
121	});
122
123	it('handles attachment content with special characters', () => {
124		const extras = [
125			{
126				content: 'const x = "hello\\nworld";\nconst y = `template ${var}`;',
127				name: 'code.js',
128				type: AttachmentType.TEXT as const
129			}
130		];
131		const formatted = formatMessageForClipboard('Check this code', extras);
132		const parsed = parseClipboardContent(formatted);
133
134		expect(parsed.textAttachments[0].content).toBe(
135			'const x = "hello\\nworld";\nconst y = `template ${var}`;'
136		);
137	});
138
139	it('handles unicode characters in content and attachments', () => {
140		const extras = [
141			{
142				content: '日本語テスト 🎉 émojis',
143				name: 'unicode.txt',
144				type: AttachmentType.TEXT as const
145			}
146		];
147		const formatted = formatMessageForClipboard('Привет мир 👋', extras);
148		const parsed = parseClipboardContent(formatted);
149
150		expect(parsed.message).toBe('Привет мир 👋');
151		expect(parsed.textAttachments[0].content).toBe('日本語テスト 🎉 émojis');
152	});
153
154	it('formats as plain text when asPlainText is true', () => {
155		const extras = [
156			{
157				content: 'File 1 content',
158				name: 'file1.txt',
159				type: AttachmentType.TEXT as const
160			},
161			{
162				content: 'File 2 content',
163				name: 'file2.txt',
164				type: AttachmentType.TEXT as const
165			}
166		];
167		const result = formatMessageForClipboard('Hello world', extras, true);
168
169		expect(result).toBe('Hello world\n\nFile 1 content\n\nFile 2 content');
170	});
171
172	it('returns plain content when asPlainText is true but no attachments', () => {
173		const result = formatMessageForClipboard('Hello world', [], true);
174
175		expect(result).toBe('Hello world');
176	});
177
178	it('plain text mode does not use JSON format', () => {
179		const extras = [
180			{
181				content: 'Test content',
182				name: 'test.txt',
183				type: AttachmentType.TEXT as const
184			}
185		];
186		const result = formatMessageForClipboard('Hello', extras, true);
187
188		expect(result).not.toContain('"type"');
189		expect(result).not.toContain('[');
190		expect(result).toBe('Hello\n\nTest content');
191	});
192});
193
194describe('parseClipboardContent', () => {
195	it('returns plain text as message when not in special format', () => {
196		const result = parseClipboardContent('Hello world');
197
198		expect(result.message).toBe('Hello world');
199		expect(result.textAttachments).toHaveLength(0);
200	});
201
202	it('handles empty string input', () => {
203		const result = parseClipboardContent('');
204
205		expect(result.message).toBe('');
206		expect(result.textAttachments).toHaveLength(0);
207	});
208
209	it('handles whitespace-only input', () => {
210		const result = parseClipboardContent('   \n\t  ');
211
212		expect(result.message).toBe('   \n\t  ');
213		expect(result.textAttachments).toHaveLength(0);
214	});
215
216	it('returns plain text as message when starts with quote but invalid format', () => {
217		const result = parseClipboardContent('"Unclosed quote');
218
219		expect(result.message).toBe('"Unclosed quote');
220		expect(result.textAttachments).toHaveLength(0);
221	});
222
223	it('returns original text when JSON array is malformed', () => {
224		const input = '"Hello"\n[invalid json';
225		const result = parseClipboardContent(input);
226
227		expect(result.message).toBe('"Hello"\n[invalid json');
228		expect(result.textAttachments).toHaveLength(0);
229	});
230
231	it('parses message with text attachments', () => {
232		const input = `"Hello world"
233[
234  {"type":"TEXT","name":"file1.txt","content":"File 1 content"},
235  {"type":"TEXT","name":"file2.txt","content":"File 2 content"}
236]`;
237		const result = parseClipboardContent(input);
238
239		expect(result.message).toBe('Hello world');
240		expect(result.textAttachments).toHaveLength(2);
241		expect(result.textAttachments[0].name).toBe('file1.txt');
242		expect(result.textAttachments[0].content).toBe('File 1 content');
243		expect(result.textAttachments[1].name).toBe('file2.txt');
244		expect(result.textAttachments[1].content).toBe('File 2 content');
245	});
246
247	it('handles escaped quotes in message', () => {
248		const input = `"Hello \\"world\\" with quotes"
249[
250  {"type":"TEXT","name":"file.txt","content":"test"}
251]`;
252		const result = parseClipboardContent(input);
253
254		expect(result.message).toBe('Hello "world" with quotes');
255		expect(result.textAttachments).toHaveLength(1);
256	});
257
258	it('handles newlines in message', () => {
259		const input = `"Hello\\nworld"
260[
261  {"type":"TEXT","name":"file.txt","content":"test"}
262]`;
263		const result = parseClipboardContent(input);
264
265		expect(result.message).toBe('Hello\nworld');
266		expect(result.textAttachments).toHaveLength(1);
267	});
268
269	it('returns message only when no array follows', () => {
270		const input = '"Just a quoted string"';
271		const result = parseClipboardContent(input);
272
273		expect(result.message).toBe('Just a quoted string');
274		expect(result.textAttachments).toHaveLength(0);
275	});
276
277	it('filters out invalid attachment objects', () => {
278		const input = `"Hello"
279[
280  {"type":"TEXT","name":"valid.txt","content":"valid"},
281  {"type":"INVALID","name":"invalid.txt","content":"invalid"},
282  {"name":"missing-type.txt","content":"missing"},
283  {"type":"TEXT","content":"missing name"}
284]`;
285		const result = parseClipboardContent(input);
286
287		expect(result.message).toBe('Hello');
288		expect(result.textAttachments).toHaveLength(1);
289		expect(result.textAttachments[0].name).toBe('valid.txt');
290	});
291
292	it('handles empty attachments array', () => {
293		const input = '"Hello"\n[]';
294		const result = parseClipboardContent(input);
295
296		expect(result.message).toBe('Hello');
297		expect(result.textAttachments).toHaveLength(0);
298	});
299
300	it('roundtrips correctly with formatMessageForClipboard', () => {
301		const originalContent = 'Hello "world" with\nspecial characters';
302		const originalExtras = [
303			{
304				content: 'Content with\nnewlines and "quotes"',
305				name: 'file1.txt',
306				type: AttachmentType.TEXT as const
307			},
308			{
309				content: 'Another file',
310				name: 'file2.txt',
311				type: AttachmentType.TEXT as const
312			}
313		];
314		const formatted = formatMessageForClipboard(originalContent, originalExtras);
315		const parsed = parseClipboardContent(formatted);
316
317		expect(parsed.message).toBe(originalContent);
318		expect(parsed.textAttachments).toHaveLength(2);
319		expect(parsed.textAttachments[0].name).toBe('file1.txt');
320		expect(parsed.textAttachments[0].content).toBe('Content with\nnewlines and "quotes"');
321		expect(parsed.textAttachments[1].name).toBe('file2.txt');
322		expect(parsed.textAttachments[1].content).toBe('Another file');
323	});
324});
325
326describe('hasClipboardAttachments', () => {
327	it('returns false for plain text', () => {
328		expect(hasClipboardAttachments('Hello world')).toBe(false);
329	});
330
331	it('returns false for empty string', () => {
332		expect(hasClipboardAttachments('')).toBe(false);
333	});
334
335	it('returns false for quoted string without attachments', () => {
336		expect(hasClipboardAttachments('"Hello world"')).toBe(false);
337	});
338
339	it('returns true for valid format with attachments', () => {
340		const input = `"Hello"
341[{"type":"TEXT","name":"file.txt","content":"test"}]`;
342
343		expect(hasClipboardAttachments(input)).toBe(true);
344	});
345
346	it('returns false for format with empty attachments array', () => {
347		const input = '"Hello"\n[]';
348
349		expect(hasClipboardAttachments(input)).toBe(false);
350	});
351
352	it('returns false for malformed JSON', () => {
353		expect(hasClipboardAttachments('"Hello"\n[broken')).toBe(false);
354	});
355});
356
357describe('roundtrip edge cases', () => {
358	it('preserves empty message with attachments', () => {
359		const extras = [
360			{
361				content: 'Content only',
362				name: 'file.txt',
363				type: AttachmentType.TEXT as const
364			}
365		];
366		const formatted = formatMessageForClipboard('', extras);
367		const parsed = parseClipboardContent(formatted);
368
369		expect(parsed.message).toBe('');
370		expect(parsed.textAttachments).toHaveLength(1);
371		expect(parsed.textAttachments[0].content).toBe('Content only');
372	});
373
374	it('preserves attachment with empty content', () => {
375		const extras = [
376			{
377				content: '',
378				name: 'empty.txt',
379				type: AttachmentType.TEXT as const
380			}
381		];
382		const formatted = formatMessageForClipboard('Message', extras);
383		const parsed = parseClipboardContent(formatted);
384
385		expect(parsed.message).toBe('Message');
386		expect(parsed.textAttachments).toHaveLength(1);
387		expect(parsed.textAttachments[0].content).toBe('');
388	});
389
390	it('preserves multiple backslashes', () => {
391		const content = 'Path: C:\\\\Users\\\\test\\\\file.txt';
392		const extras = [
393			{
394				content: 'D:\\\\Data\\\\file',
395				name: 'path.txt',
396				type: AttachmentType.TEXT as const
397			}
398		];
399		const formatted = formatMessageForClipboard(content, extras);
400		const parsed = parseClipboardContent(formatted);
401
402		expect(parsed.message).toBe(content);
403		expect(parsed.textAttachments[0].content).toBe('D:\\\\Data\\\\file');
404	});
405
406	it('preserves tabs and various whitespace', () => {
407		const content = 'Line1\t\tTabbed\n  Spaced\r\nCRLF';
408		const extras = [
409			{
410				content: '\t\t\n\n   ',
411				name: 'whitespace.txt',
412				type: AttachmentType.TEXT as const
413			}
414		];
415		const formatted = formatMessageForClipboard(content, extras);
416		const parsed = parseClipboardContent(formatted);
417
418		expect(parsed.message).toBe(content);
419		expect(parsed.textAttachments[0].content).toBe('\t\t\n\n   ');
420	});
421});