This commit is contained in:
Tomas Dvorak
2026-02-24 10:33:59 +01:00
parent 409acd2e08
commit 898a3c303f
1374 changed files with 290409 additions and 29187 deletions
+2 -16
View File
@@ -1,11 +1,11 @@
package dockerdocs
import (
"net/url"
"strings"
"time"
"github.com/PuerkitoBio/goquery"
"github.com/yourorg/devour/pkg/parserutil"
)
type Parser struct {
@@ -182,19 +182,5 @@ func (p *Parser) extractLinks(doc *goquery.Document, baseURL string) []string {
}
func resolveURL(base string, href string) string {
if strings.HasPrefix(href, "http") {
return href
}
baseURL, err := url.Parse(base)
if err != nil {
return href
}
hrefURL, err := url.Parse(href)
if err != nil {
return href
}
return baseURL.ResolveReference(hrefURL).String()
return parserutil.ResolveURL(base, href)
}
+89
View File
@@ -0,0 +1,89 @@
package dockerdocs
import "testing"
const testDockerPageHTML = `
<!DOCTYPE html>
<html>
<head>
<title>Docker Compose | Docker Docs</title>
<meta name="description" content="Define and run multi-container applications.">
</head>
<body>
<article>
<h1 id="compose">Docker Compose</h1>
<p>Compose is for defining and running multi-container Docker apps.</p>
<h2 id="quickstart">Quickstart</h2>
<p>Use docker compose up.</p>
<pre><code class="language-bash">docker compose up</code></pre>
<a href="/compose/install/">Install</a>
<a href="https://docs.docker.com/engine/">Engine</a>
</article>
</body>
</html>
`
func TestParsePage(t *testing.T) {
parser := NewParser()
page, err := parser.ParsePage(testDockerPageHTML, "https://docs.docker.com/compose/")
if err != nil {
t.Fatalf("ParsePage failed: %v", err)
}
if page.Title != "Docker Compose" {
t.Fatalf("unexpected title: %q", page.Title)
}
if page.Description == "" {
t.Fatal("expected non-empty description")
}
if len(page.Sections) < 2 {
t.Fatalf("expected at least 2 sections, got %d", len(page.Sections))
}
if len(page.CodeBlocks) == 0 {
t.Fatal("expected at least one code block")
}
foundBash := false
for _, block := range page.CodeBlocks {
if block.Language == "bash" {
foundBash = true
break
}
}
if !foundBash {
t.Fatalf("expected at least one bash code block, got %+v", page.CodeBlocks)
}
if len(page.Links) < 2 {
t.Fatalf("expected at least 2 links, got %d", len(page.Links))
}
}
func TestParseToc(t *testing.T) {
parser := NewParser()
html := `
<nav>
<a href="/compose/install/">Install</a>
<a href="/compose/how-tos/">How-tos</a>
</nav>`
sections, err := parser.ParseToc(html)
if err != nil {
t.Fatalf("ParseToc failed: %v", err)
}
if len(sections) != 2 {
t.Fatalf("expected 2 sections, got %d", len(sections))
}
if sections[0].DocURL != "https://docs.docker.com/compose/install/" {
t.Fatalf("unexpected resolved URL: %q", sections[0].DocURL)
}
}
func TestResolveURL(t *testing.T) {
got := resolveURL("https://docs.docker.com", "/compose/")
if got != "https://docs.docker.com/compose/" {
t.Fatalf("resolveURL returned %q", got)
}
}