UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

192 lines (155 loc) • 8.01 kB
// @vitest-environment node import { describe, expect, it } from 'vitest'; import { splitPromptForDualCLIP } from '@/server/services/comfyui/utils/promptSplitter'; describe('splitPromptForDualCLIP', () => { it('should handle empty or null prompt', () => { expect(splitPromptForDualCLIP('')).toEqual({ clipLPrompt: '', t5xxlPrompt: '', }); expect(splitPromptForDualCLIP(null as any)).toEqual({ clipLPrompt: '', t5xxlPrompt: '', }); expect(splitPromptForDualCLIP(undefined as any)).toEqual({ clipLPrompt: '', t5xxlPrompt: '', }); }); it('should split prompt with style keywords', () => { const prompt = 'a beautiful landscape, photorealistic, high quality, cinematic lighting'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('photorealistic'); expect(result.clipLPrompt).toContain('high quality'); expect(result.clipLPrompt).toContain('cinematic'); }); it('should extract single-word style keywords', () => { const prompt = 'a cat sitting, realistic, detailed, masterpiece'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('realistic'); expect(result.clipLPrompt).toContain('detailed'); expect(result.clipLPrompt).toContain('masterpiece'); expect(result.clipLPrompt).not.toContain('cat'); expect(result.clipLPrompt).not.toContain('sitting'); }); it('should extract multi-word style keywords', () => { const prompt = 'beautiful girl portrait, digital art, depth of field, trending on artstation'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('digital art'); expect(result.clipLPrompt).toContain('depth of field'); expect(result.clipLPrompt).toContain('trending on artstation'); }); it('should handle lighting keywords', () => { const prompt = 'sunset over ocean, dramatic lighting, golden hour, soft lighting'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('dramatic lighting'); expect(result.clipLPrompt).toContain('golden hour'); expect(result.clipLPrompt).toContain('soft lighting'); }); it('should handle quality keywords', () => { const prompt = 'mountain view, 4k, ultra detailed, best quality, highly detailed'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('4k'); expect(result.clipLPrompt).toContain('ultra detailed'); expect(result.clipLPrompt).toContain('best quality'); expect(result.clipLPrompt).toContain('highly detailed'); }); it('should handle photography terms', () => { const prompt = 'city street, bokeh, motion blur, wide angle, macro shot'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('bokeh'); expect(result.clipLPrompt).toContain('motion blur'); expect(result.clipLPrompt).toContain('wide angle'); expect(result.clipLPrompt).toContain('macro'); }); it('should handle artist and platform keywords', () => { const prompt = 'fantasy landscape, by greg rutkowski, concept art, octane render'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('by greg rutkowski'); expect(result.clipLPrompt).toContain('concept art'); expect(result.clipLPrompt).toContain('octane render'); }); it('should fallback to adjectives when no style keywords found', () => { const prompt = 'a beautiful sunny day with colorful flowers blooming magnificently'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); // Should contain adjective-like words that match the regex pattern expect(result.clipLPrompt).toMatch(/blooming|magnificently|colorful|beautiful|sunny/); expect(result.clipLPrompt.length).toBeGreaterThan(0); }); it('should use same prompt for both when no style words or adjectives', () => { const prompt = 'cat dog house tree'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toBe(prompt); }); it('should preserve original case in style words', () => { const prompt = 'Portrait of girl, Photorealistic, High Quality, Digital Art'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('Photorealistic'); expect(result.clipLPrompt).toContain('High Quality'); expect(result.clipLPrompt).toContain('Digital Art'); }); it('should handle comma-separated prompts', () => { const prompt = 'forest path, cinematic, dramatic lighting, 8k, masterpiece'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('cinematic'); expect(result.clipLPrompt).toContain('dramatic lighting'); expect(result.clipLPrompt).toContain('8k'); expect(result.clipLPrompt).toContain('masterpiece'); }); it('should handle partial keyword matches correctly', () => { const prompt = 'realistic portrait, photo-realistic style, realism art'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); // Should match "realistic" but exact behavior depends on implementation expect(result.clipLPrompt.length).toBeGreaterThan(0); }); it('should handle overlapping multi-word keywords', () => { const prompt = 'art gallery, digital art work, concept art design'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('digital art'); expect(result.clipLPrompt).toContain('concept art'); }); it('should work with very long prompts', () => { const prompt = 'An incredibly detailed and photorealistic portrait of a young woman with flowing hair, sitting in a beautiful garden during golden hour, with soft lighting and dramatic shadows, rendered in 8k ultra high quality with perfect focus and depth of field, trending on artstation, masterpiece'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('photorealistic'); expect(result.clipLPrompt).toContain('golden hour'); expect(result.clipLPrompt).toContain('soft lighting'); expect(result.clipLPrompt).toContain('8k'); expect(result.clipLPrompt).toContain('depth of field'); expect(result.clipLPrompt).toContain('trending on artstation'); expect(result.clipLPrompt).toContain('masterpiece'); }); it('should handle mixed content with various separators', () => { const prompt = 'sunset landscape; cinematic mood, soft lighting. 4k resolution!'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); expect(result.clipLPrompt).toContain('cinematic'); // soft lighting might be treated as two separate words due to separator handling expect(result.clipLPrompt).toMatch(/soft|lighting|cinematic|4k/); }); it('should prioritize style keywords over content words', () => { const prompt = 'beautiful mountain landscape, photorealistic, detailed'; const result = splitPromptForDualCLIP(prompt); expect(result.t5xxlPrompt).toBe(prompt); // Should contain style keywords expect(result.clipLPrompt).toContain('photorealistic'); expect(result.clipLPrompt).toContain('detailed'); // The algorithm extracts style keywords first, so may not contain content words expect(result.clipLPrompt.length).toBeGreaterThan(0); }); });