mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-04 04:23:02 +00:00
first commit
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
package pythondocs
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
)
|
||||
|
||||
const testModulePageHTML = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div class="body" role="main">
|
||||
<section id="module-test">
|
||||
<h1><code class="xref py py-mod docutils literal notranslate"><span class="pre">test</span></code> — Regression tests package<a class="headerlink" href="#module-test">¶</a></h1>
|
||||
<p>The test package contains all regression tests for Python.</p>
|
||||
<p>This is additional documentation.</p>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="test.TestCase">
|
||||
<em class="property"><span class="pre">class</span></em>
|
||||
<span class="sig-prename descclassname"><span class="pre">test.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">TestCase</span></span>
|
||||
<span class="sig-paren">(</span><em class="sig-param"><span class="pre">methodName</span><span class="pre">=</span><span class="pre">'runTest'</span></em><span class="sig-paren">)</span>
|
||||
<a class="headerlink" href="#test.TestCase">¶</a>
|
||||
</dt>
|
||||
<dd><p>A test case class.</p></dd>
|
||||
</dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dt class="sig sig-object py" id="test.run_test">
|
||||
<span class="sig-prename descclassname"><span class="pre">test.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">run_test</span></span>
|
||||
<span class="sig-paren">(</span><em class="sig-param"><span class="pre">name</span></em>, <em class="sig-param"><span class="pre">verbose</span><span class="pre">=</span><span class="pre">False</span></em><span class="sig-paren">)</span>
|
||||
<a class="headerlink" href="#test.run_test">¶</a>
|
||||
</dt>
|
||||
<dd><p>Run a single test.</p></dd>
|
||||
</dl>
|
||||
|
||||
<dl class="py exception">
|
||||
<dt class="sig sig-object py" id="test.TestFailed">
|
||||
<em class="property"><span class="pre">exception</span></em>
|
||||
<span class="sig-prename descclassname"><span class="pre">test.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">TestFailed</span></span>
|
||||
<a class="headerlink" href="#test.TestFailed">¶</a>
|
||||
</dt>
|
||||
<dd><p>Exception raised when a test fails.</p></dd>
|
||||
</dl>
|
||||
|
||||
<dl class="py data">
|
||||
<dt class="sig sig-object py" id="test.verbose">
|
||||
<span class="sig-prename descclassname"><span class="pre">test.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">verbose</span></span>
|
||||
<a class="headerlink" href="#test.verbose">¶</a>
|
||||
</dt>
|
||||
<dd><p>True when verbose output is enabled.</p></dd>
|
||||
</dl>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
const testClassHTML = `
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="test.TestCase">
|
||||
<em class="property"><span class="pre">class</span></em>
|
||||
<span class="sig-prename descclassname"><span class="pre">test.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">TestCase</span></span>
|
||||
<span class="sig-paren">(</span><em class="sig-param"><span class="pre">methodName</span><span class="pre">=</span><span class="pre">'runTest'</span></em><span class="sig-paren">)</span>
|
||||
</dt>
|
||||
<dd>
|
||||
<p>A test case class that provides testing functionality.</p>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="test.TestCase.setUp">
|
||||
<span class="sig-prename descclassname"><span class="pre">test.TestCase.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">setUp</span></span>
|
||||
<span class="sig-paren">(</span><span class="sig-paren">)</span>
|
||||
</dt>
|
||||
<dd><p>Set up the test fixture.</p></dd>
|
||||
</dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="test.TestCase.tearDown">
|
||||
<span class="sig-prename descclassname"><span class="pre">test.TestCase.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">tearDown</span></span>
|
||||
<span class="sig-paren">(</span><span class="sig-paren">)</span>
|
||||
</dt>
|
||||
<dd><p>Tear down the test fixture.</p></dd>
|
||||
</dl>
|
||||
|
||||
<dl class="py classmethod">
|
||||
<dt class="sig sig-object py" id="test.TestCase.setUpClass">
|
||||
<em class="property"><span class="pre">classmethod</span></em>
|
||||
<span class="sig-prename descclassname"><span class="pre">test.TestCase.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">setUpClass</span></span>
|
||||
<span class="sig-paren">(</span><span class="sig-paren">)</span>
|
||||
</dt>
|
||||
<dd><p>Set up the test class.</p></dd>
|
||||
</dl>
|
||||
|
||||
<dl class="py attribute">
|
||||
<dt class="sig sig-object py" id="test.TestCase.maxDiff">
|
||||
<span class="sig-prename descclassname"><span class="pre">test.TestCase.</span></span>
|
||||
<span class="sig-name descname"><span class="pre">maxDiff</span></span>
|
||||
</dt>
|
||||
<dd><p>Maximum diff length.</p></dd>
|
||||
</dl>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
`
|
||||
|
||||
const testSearchHTML = `
|
||||
<ul class="search">
|
||||
<li class="kind-object">
|
||||
<a href="library/test.html#module-test" data-score="26">test</a>
|
||||
<span>(Python module, in test — Regression tests package)</span>
|
||||
</li>
|
||||
<li class="kind-object">
|
||||
<a href="library/unittest.html#module-unittest" data-score="21">unittest</a>
|
||||
<span>(Python module, in unittest — Unit testing framework)</span>
|
||||
</li>
|
||||
<li class="kind-text">
|
||||
<a href="library/keyword.html" data-score="15">keyword — Testing for Python keywords</a>
|
||||
<p class="context">This module allows a Python program to determine if a string is a keyword.</p>
|
||||
</li>
|
||||
</ul>
|
||||
`
|
||||
|
||||
func TestParseModulePage(t *testing.T) {
|
||||
parser := NewParser()
|
||||
module, err := parser.ParseModulePage(testModulePageHTML, "https://docs.python.org/3/library/test.html")
|
||||
if err != nil {
|
||||
t.Fatalf("ParseModulePage failed: %v", err)
|
||||
}
|
||||
|
||||
if module.Name == "" {
|
||||
t.Error("Expected non-empty module name")
|
||||
}
|
||||
|
||||
if module.Doc == "" {
|
||||
t.Error("Expected non-empty doc")
|
||||
}
|
||||
|
||||
if len(module.Classes) == 0 {
|
||||
t.Error("Expected at least one class")
|
||||
}
|
||||
|
||||
if len(module.Functions) == 0 {
|
||||
t.Error("Expected at least one function")
|
||||
}
|
||||
|
||||
if len(module.Exceptions) == 0 {
|
||||
t.Error("Expected at least one exception")
|
||||
}
|
||||
|
||||
if len(module.Constants) == 0 {
|
||||
t.Error("Expected at least one constant/data")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSearchResults(t *testing.T) {
|
||||
parser := NewParser()
|
||||
results, err := parser.ParseSearchResults(testSearchHTML)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseSearchResults failed: %v", err)
|
||||
}
|
||||
|
||||
if len(results) < 2 {
|
||||
t.Fatalf("Expected at least 2 results, got %d", len(results))
|
||||
}
|
||||
|
||||
first := results[0]
|
||||
if first.Name == "" {
|
||||
t.Error("Expected non-empty name")
|
||||
}
|
||||
|
||||
if first.DocURL == "" {
|
||||
t.Error("Expected non-empty doc URL")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractClasses(t *testing.T) {
|
||||
parser := NewParser()
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(testClassHTML))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse HTML: %v", err)
|
||||
}
|
||||
|
||||
classes := parser.extractClasses(doc, "test", "https://docs.python.org/3/library/test.html")
|
||||
|
||||
if len(classes) == 0 {
|
||||
t.Fatal("Expected at least one class")
|
||||
}
|
||||
|
||||
tc := classes[0]
|
||||
if tc.Name == "" {
|
||||
t.Error("Expected non-empty class name")
|
||||
}
|
||||
|
||||
if len(tc.Methods) < 2 {
|
||||
t.Errorf("Expected at least 2 methods, got %d", len(tc.Methods))
|
||||
}
|
||||
|
||||
if len(tc.ClassMethods) == 0 {
|
||||
t.Error("Expected at least one classmethod")
|
||||
}
|
||||
|
||||
if len(tc.Attributes) == 0 {
|
||||
t.Error("Expected at least one attribute")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractFunctions(t *testing.T) {
|
||||
parser := NewParser()
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(testModulePageHTML))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse HTML: %v", err)
|
||||
}
|
||||
|
||||
functions := parser.extractFunctions(doc, "test", "https://docs.python.org/3/library/test.html")
|
||||
|
||||
if len(functions) == 0 {
|
||||
t.Fatal("Expected at least one function")
|
||||
}
|
||||
|
||||
fn := functions[0]
|
||||
if fn.Name == "" {
|
||||
t.Error("Expected non-empty function name")
|
||||
}
|
||||
|
||||
if fn.Signature == "" {
|
||||
t.Error("Expected non-empty signature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
base string
|
||||
href string
|
||||
expected string
|
||||
}{
|
||||
{"https://docs.python.org", "/library/test.html", "https://docs.python.org/library/test.html"},
|
||||
{"https://docs.python.org", "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 TestExtractPathFromURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
href string
|
||||
expected string
|
||||
}{
|
||||
{"/library/test.html", "library/test"},
|
||||
{"library/test.html", "library/test"},
|
||||
{"/library/test.html#module-test", "library/test"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.href, func(t *testing.T) {
|
||||
got := extractPathFromURL(tt.href)
|
||||
if got != tt.expected {
|
||||
t.Errorf("extractPathFromURL(%q) = %q, want %q", tt.href, got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user