mirror of
https://github.com/PuerkitoBio/goquery
synced 2025-12-24 12:38:00 +08:00
Test and benchmark the Single[Matcher] funcs
This commit is contained in:
@@ -2,6 +2,8 @@ package goquery
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/andybalholm/cascadia"
|
||||
)
|
||||
|
||||
func BenchmarkFind(b *testing.B) {
|
||||
@@ -800,3 +802,21 @@ func BenchmarkClosestNodes(b *testing.B) {
|
||||
b.Fatalf("want 2, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSingleMatcher(b *testing.B) {
|
||||
doc := Doc()
|
||||
multi := cascadia.MustCompile(`div`)
|
||||
single := SingleMatcher(multi)
|
||||
b.ResetTimer()
|
||||
|
||||
b.Run("multi", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = doc.FindMatcher(multi)
|
||||
}
|
||||
})
|
||||
b.Run("single", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = doc.FindMatcher(single)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
18
type.go
18
type.go
@@ -124,9 +124,17 @@ type Matcher interface {
|
||||
// Single compiles a selector string to a Matcher that stops after the first
|
||||
// match is found.
|
||||
//
|
||||
// By default, Selection.Find and other functions that accept a selector string
|
||||
// will use all matches corresponding to that selector. By using the Matcher
|
||||
// returned by Single, at most the first match will be used.
|
||||
// By default, Selection.Find and other functions that accept a selector
|
||||
// string to find nodes will use all matches corresponding to that selector.
|
||||
// By using the Matcher returned by Single, at most the first match will be
|
||||
// used.
|
||||
//
|
||||
// Note that the single-selection property of the Matcher only applies for
|
||||
// methods where the Matcher is used to select nodes, not to filter or check
|
||||
// if a node matches the Matcher - in those cases, the behaviour of the
|
||||
// Matcher is unchanged (e.g. FilterMatcher(Single("div")) will still result
|
||||
// in a Selection with multiple "div"s if there were many "div"s in the
|
||||
// Selection to begin with).
|
||||
func Single(selector string) Matcher {
|
||||
return singleMatcher{compileMatcher(selector)}
|
||||
}
|
||||
@@ -134,9 +142,7 @@ func Single(selector string) Matcher {
|
||||
// SingleMatcher returns a Matcher matches the same nodes as m, but that stops
|
||||
// after the first match is found.
|
||||
//
|
||||
// By default, Selection.FindMatcher and other functions that accept a Matcher
|
||||
// will use all corresponding matches. By using the Matcher returned by
|
||||
// SingleMatcher, at most the first match will be used.
|
||||
// See the documentation of function Single for more details.
|
||||
func SingleMatcher(m Matcher) Matcher {
|
||||
if _, ok := m.(singleMatcher); ok {
|
||||
// m is already a singleMatcher
|
||||
|
||||
38
type_test.go
38
type_test.go
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/andybalholm/cascadia"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
@@ -208,3 +209,40 @@ func TestIssue103(t *testing.T) {
|
||||
}
|
||||
t.Log(text)
|
||||
}
|
||||
|
||||
func TestSingle(t *testing.T) {
|
||||
data := `
|
||||
<html>
|
||||
<body>
|
||||
<div class="b">1</div>
|
||||
<div class="a">2</div>
|
||||
<div class="a">3</div>
|
||||
<p class="b">4</p>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
doc, err := NewDocumentFromReader(strings.NewReader(data))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
text := doc.FindMatcher(Single("div")).Text()
|
||||
if text != "1" {
|
||||
t.Fatalf("want %q, got %q", "1", text)
|
||||
}
|
||||
|
||||
// Here, the Single has no effect as the selector is used to filter
|
||||
// from the existing selection, not to find nodes in the document.
|
||||
divs := doc.Find("div")
|
||||
text = divs.FilterMatcher(Single(".a")).Text()
|
||||
if text != "23" {
|
||||
t.Fatalf("want %q, got %q", "23", text)
|
||||
}
|
||||
|
||||
classA := cascadia.MustCompile(".a")
|
||||
classB := cascadia.MustCompile(".b")
|
||||
text = doc.FindMatcher(classB).AddMatcher(SingleMatcher(classA)).Text()
|
||||
if text != "142" {
|
||||
t.Fatalf("want %q, got %q", "142", text)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user