package docx import ( "strings" "testing" ) func TestStyleExtractor_Extract(t *testing.T) { fixture := `# Professional Summary ## Summary Experienced software engineer with 10 years of expertise in cloud infrastructure and backend systems. Passionate about building scalable, maintainable solutions that drive business value. ## Experience ### Senior Engineer at TechCorp (2020-2024) - Designed microservices architecture handling 1M+ requests/day - Implemented CI/CD pipeline reducing deployment time by 60% - Led team of 5 engineers on critical infrastructure project - Optimized database queries improving response time by 40% - Mentored junior developers and conducted code reviews ### Engineer at StartupXYZ (2018-2020) - Built REST API from scratch using Go and PostgreSQL - Deployed applications to Kubernetes cluster - Fixed critical production bugs within SLA requirements - Developed monitoring dashboard for system observability - Contributed to open source projects during hackathons ## Skills - Languages: Go, Python, JavaScript - Tools: Kubernetes, Docker, PostgreSQL ` extractor := NewStyleExtractor(fixture) profile := extractor.Extract() // Test action verbs: should extract and deduplicate if len(profile.ActionVerbs) == 0 { t.Errorf("Expected action verbs, got empty list") } if len(profile.ActionVerbs) > 20 { t.Errorf("Expected max 20 action verbs, got %d", len(profile.ActionVerbs)) } // Check some common verbs are present hasDesigned := false hasImplemented := false for _, v := range profile.ActionVerbs { if v == "designed" { hasDesigned = true } if v == "implemented" { hasImplemented = true } } if !hasDesigned || !hasImplemented { t.Errorf("Expected 'designed' and 'implemented' in action verbs, got %v", profile.ActionVerbs) } // Test summary: should find Summary section and extract 2 sentences if profile.SummaryStyle == "" { t.Errorf("Expected summary style, got empty string") } if !strings.Contains(profile.SummaryStyle, "software engineer") { t.Errorf("Expected 'software engineer' in summary, got %q", profile.SummaryStyle) } if !strings.Contains(profile.SummaryStyle, "scalable") { t.Errorf("Expected 'scalable' in summary, got %q", profile.SummaryStyle) } // Test bullet patterns: should extract first 5 words of bullets (up to 30) if len(profile.BulletPatterns) == 0 { t.Errorf("Expected bullet patterns, got empty list") } if len(profile.BulletPatterns) > 30 { t.Errorf("Expected max 30 bullet patterns, got %d", len(profile.BulletPatterns)) } // Each pattern should have at most 5 words for i, pattern := range profile.BulletPatterns { words := strings.Fields(pattern) if len(words) > 5 { t.Errorf("Pattern %d has %d words (max 5), pattern: %q", i, len(words), pattern) } } } func TestStyleExtractor_ActionVerbDedupe(t *testing.T) { fixture := `## Experience - Built system architecture - Built API endpoints - Built deployment pipeline - Designed database schema - Implemented feature X ` extractor := NewStyleExtractor(fixture) profile := extractor.Extract() // Verify that 'built' appears only once in actionVerbs (deduped) builtCount := 0 for _, v := range profile.ActionVerbs { if v == "built" { builtCount++ } } if builtCount != 1 { t.Errorf("Expected 'built' to appear once after deduplication, got %d times", builtCount) } // 'built' should be first (highest frequency) if len(profile.ActionVerbs) > 0 && profile.ActionVerbs[0] != "built" { t.Errorf("Expected 'built' to be first (highest freq), got %v", profile.ActionVerbs[0]) } } func TestStyleExtractor_NoSummary(t *testing.T) { fixture := `## Experience - Did something - Did another thing ` extractor := NewStyleExtractor(fixture) profile := extractor.Extract() if profile.SummaryStyle != "" { t.Errorf("Expected empty summary when no Summary section found, got %q", profile.SummaryStyle) } } func TestStyleExtractor_BulletLimitedWords(t *testing.T) { fixture := `## Experience - First second third fourth fifth sixth seventh eighth - Another pattern with lots and lots of words ` extractor := NewStyleExtractor(fixture) profile := extractor.Extract() if len(profile.BulletPatterns) < 2 { t.Fatalf("Expected at least 2 bullet patterns, got %d", len(profile.BulletPatterns)) } // First pattern should have only 5 words pattern := profile.BulletPatterns[0] words := strings.Fields(pattern) if len(words) != 5 { t.Errorf("Expected 5 words in first pattern, got %d: %q", len(words), pattern) } if !strings.HasPrefix(pattern, "First second third fourth fifth") { t.Errorf("Expected pattern to start with 'First second third fourth fifth', got %q", pattern) } }