package rustdocs import ( "strings" "testing" "github.com/PuerkitoBio/goquery" ) const testStructPageHTML = `

Struct Mask

1.0.0
pub struct Mask<T, const N: usize>(/* private fields */)

A SIMD vector mask for N elements.

Implementations

pub fn test(&self, index: usize) -> bool

Tests the value of the specified element.

` const testSearchHTML = `
` const testCratePageHTML = `

Crate serde

1.0.0

A framework for serializing and deserializing Rust data structures.

Modules

de
Deserialize implementation.

Structs

Serializer
A structure for serializing Rust values.

Enums

Error
Errors during serialization.
` func TestParseItemPage(t *testing.T) { parser := NewParser() symbol, err := parser.ParseItemPage(testStructPageHTML, "https://docs.rs/std/simd/struct.Mask.html") if err != nil { t.Fatalf("ParseItemPage failed: %v", err) } if symbol.Name != "Mask" { t.Errorf("Expected name 'Mask', got '%s'", symbol.Name) } if symbol.Kind != ItemKindStruct { t.Errorf("Expected kind 'struct', got '%s'", symbol.Kind) } if symbol.Doc == "" { t.Error("Expected non-empty doc") } if !strings.Contains(symbol.Signature, "struct Mask") { t.Errorf("Expected signature to contain 'struct Mask', got '%s'", symbol.Signature) } } func TestParseSearchResults(t *testing.T) { parser := NewParser() results, err := parser.ParseSearchResults(testSearchHTML) if err != nil { t.Fatalf("ParseSearchResults failed: %v", err) } if len(results) < 3 { t.Fatalf("Expected at least 3 results, got %d", len(results)) } method := results[0] if method.Kind != "fn" { t.Errorf("Expected kind 'fn' for method, got '%s'", method.Kind) } if method.Description == "" { t.Error("Expected non-empty description") } structResult := results[1] if structResult.Kind != "struct" { t.Errorf("Expected kind 'struct', got '%s'", structResult.Kind) } fnResult := results[2] if fnResult.Kind != "fn" { t.Errorf("Expected kind 'fn', got '%s'", fnResult.Kind) } } func TestParseCratePage(t *testing.T) { parser := NewParser() crate, err := parser.ParseCratePage(testCratePageHTML, "https://docs.rs/serde") if err != nil { t.Fatalf("ParseCratePage failed: %v", err) } if crate.Name == "" { t.Error("Expected non-empty name") } if crate.Description == "" { t.Error("Expected non-empty description") } } func TestExtractKindFromClasses(t *testing.T) { tests := []struct { classes string expected string }{ {"result-struct", "struct"}, {"result-enum", "enum"}, {"result-trait", "trait"}, {"result-fn", "fn"}, {"result-macro", "macro"}, {"result-const", "const"}, {"result-static", "static"}, {"result-mod", "mod"}, {"result-method", "fn"}, {"result-externcrate", "mod"}, {"unknown-class", ""}, } for _, tt := range tests { t.Run(tt.classes, func(t *testing.T) { got := extractKindFromClasses(tt.classes) if got != tt.expected { t.Errorf("extractKindFromClasses(%q) = %q, want %q", tt.classes, got, tt.expected) } }) } } func TestResolveURL(t *testing.T) { tests := []struct { base string href string expected string }{ {"https://docs.rs", "/serde/struct.Serializer.html", "https://docs.rs/serde/struct.Serializer.html"}, {"https://docs.rs", "https://example.com/page", "https://example.com/page"}, } for _, tt := range tests { t.Run(tt.href, func(t *testing.T) { got := resolveURL(tt.base, tt.href) if got != tt.expected { t.Errorf("resolveURL(%q, %q) = %q, want %q", tt.base, tt.href, got, tt.expected) } }) } } func TestCleanText(t *testing.T) { tests := []struct { input string expected string }{ {" hello world ", "hello world"}, {"single", "single"}, {"\n\ttabs\t\n", "tabs"}, } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { if got := cleanText(tt.input); got != tt.expected { t.Errorf("cleanText(%q) = %q, want %q", tt.input, got, tt.expected) } }) } } func TestExtractItemPath(t *testing.T) { parser := NewParser() html := `
std::simd
` doc, err := goquery.NewDocumentFromReader(strings.NewReader(html)) if err != nil { t.Fatalf("Failed to parse HTML: %v", err) } got := parser.extractItemPath(doc, "https://docs.rs/std/simd/struct.Mask.html") if !strings.Contains(got, "std") || !strings.Contains(got, "simd") { t.Errorf("extractItemPath() = %q, expected to contain std and simd", got) } } func TestExtractMethods(t *testing.T) { parser := NewParser() doc, err := goquery.NewDocumentFromReader(strings.NewReader(testStructPageHTML)) if err != nil { t.Fatalf("Failed to parse HTML: %v", err) } methods := parser.ExtractMethods(doc) if len(methods) == 0 { t.Error("Expected at least one method") return } if methods[0].Name == "" { t.Error("Expected non-empty method name") } }