mirror of
https://github.com/PuerkitoBio/goquery
synced 2025-10-30 11:16:21 +08:00
add Parent() and ParentFiltered(), refactor tests using Asserts...()
This commit is contained in:
@@ -6,25 +6,18 @@ import (
|
|||||||
|
|
||||||
func TestFirst(t *testing.T) {
|
func TestFirst(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").First()
|
sel := Doc().Root.Find(".pvk-content").First()
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFirstEmpty(t *testing.T) {
|
func TestFirstEmpty(t *testing.T) {
|
||||||
defer func() {
|
defer AssertPanic(t)
|
||||||
if e := recover(); e == nil {
|
|
||||||
t.Error("Expected a panic, First() called on empty Selection.")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
Doc().Root.Find(".pvk-zzcontentzz").First()
|
Doc().Root.Find(".pvk-zzcontentzz").First()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLast(t *testing.T) {
|
func TestLast(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").Last()
|
sel := Doc().Root.Find(".pvk-content").Last()
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
// Should contain Footer
|
// Should contain Footer
|
||||||
foot := Doc().Root.Find(".footer")
|
foot := Doc().Root.Find(".footer")
|
||||||
if !sel.Contains(foot.Nodes[0]) {
|
if !sel.Contains(foot.Nodes[0]) {
|
||||||
@@ -34,16 +27,13 @@ func TestLast(t *testing.T) {
|
|||||||
|
|
||||||
func TestEq(t *testing.T) {
|
func TestEq(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").Eq(1)
|
sel := Doc().Root.Find(".pvk-content").Eq(1)
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEqNegative(t *testing.T) {
|
func TestEqNegative(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").Eq(-1)
|
sel := Doc().Root.Find(".pvk-content").Eq(-1)
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
// Should contain Footer
|
// Should contain Footer
|
||||||
foot := Doc().Root.Find(".footer")
|
foot := Doc().Root.Find(".footer")
|
||||||
if !sel.Contains(foot.Nodes[0]) {
|
if !sel.Contains(foot.Nodes[0]) {
|
||||||
@@ -53,17 +43,12 @@ func TestEqNegative(t *testing.T) {
|
|||||||
|
|
||||||
func TestSlice(t *testing.T) {
|
func TestSlice(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").Slice(0, 2)
|
sel := Doc().Root.Find(".pvk-content").Slice(0, 2)
|
||||||
if len(sel.Nodes) != 2 {
|
|
||||||
t.Errorf("Expected 2 nodes, found %v.", len(sel.Nodes))
|
AssertLength(t, sel.Nodes, 2)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSliceOutOfBounds(t *testing.T) {
|
func TestSliceOutOfBounds(t *testing.T) {
|
||||||
defer func() {
|
defer AssertPanic(t)
|
||||||
if e := recover(); e == nil {
|
|
||||||
t.Error("Expected a panic, Slice() called with out of bounds indices.")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
Doc().Root.Find(".pvk-content").Slice(2, 12)
|
Doc().Root.Find(".pvk-content").Slice(2, 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,12 +69,7 @@ func TestGetNegative(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetInvalid(t *testing.T) {
|
func TestGetInvalid(t *testing.T) {
|
||||||
defer func() {
|
defer AssertPanic(t)
|
||||||
if e := recover(); e == nil {
|
|
||||||
t.Error("Expected a panic, Get() called with out of bounds index.")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
sel := Doc().Root.Find(".pvk-content")
|
sel := Doc().Root.Find(".pvk-content")
|
||||||
sel.Get(129)
|
sel.Get(129)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,52 +6,37 @@ import (
|
|||||||
|
|
||||||
func TestAdd(t *testing.T) {
|
func TestAdd(t *testing.T) {
|
||||||
sel := Doc().Root.Find("div.row-fluid").Add("a")
|
sel := Doc().Root.Find("div.row-fluid").Add("a")
|
||||||
if len(sel.Nodes) != 19 {
|
AssertLength(t, sel.Nodes, 19)
|
||||||
t.Errorf("Expected 19 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddSelection(t *testing.T) {
|
func TestAddSelection(t *testing.T) {
|
||||||
sel := Doc().Root.Find("div.row-fluid")
|
sel := Doc().Root.Find("div.row-fluid")
|
||||||
sel2 := Doc().Root.Find("a")
|
sel2 := Doc().Root.Find("a")
|
||||||
sel = sel.AddSelection(sel2)
|
sel = sel.AddSelection(sel2)
|
||||||
if len(sel.Nodes) != 19 {
|
AssertLength(t, sel.Nodes, 19)
|
||||||
t.Errorf("Expected 19 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddSelectionNil(t *testing.T) {
|
func TestAddSelectionNil(t *testing.T) {
|
||||||
sel := Doc().Root.Find("div.row-fluid")
|
sel := Doc().Root.Find("div.row-fluid")
|
||||||
if len(sel.Nodes) != 9 {
|
AssertLength(t, sel.Nodes, 9)
|
||||||
t.Errorf("Expected div.row-fluid to have 9 nodes, found %v.",
|
|
||||||
len(sel.Nodes))
|
|
||||||
}
|
|
||||||
sel = sel.AddSelection(nil)
|
sel = sel.AddSelection(nil)
|
||||||
if len(sel.Nodes) != 9 {
|
AssertLength(t, sel.Nodes, 9)
|
||||||
t.Errorf("Expected add nil to keep it to 9 nodes, found %v.",
|
|
||||||
len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddNodes(t *testing.T) {
|
func TestAddNodes(t *testing.T) {
|
||||||
sel := Doc().Root.Find("div.pvk-gutter")
|
sel := Doc().Root.Find("div.pvk-gutter")
|
||||||
sel2 := Doc().Root.Find(".pvk-content")
|
sel2 := Doc().Root.Find(".pvk-content")
|
||||||
sel = sel.AddNodes(sel2.Nodes...)
|
sel = sel.AddNodes(sel2.Nodes...)
|
||||||
if len(sel.Nodes) != 9 {
|
AssertLength(t, sel.Nodes, 9)
|
||||||
t.Errorf("Expected 9 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddNodesNone(t *testing.T) {
|
func TestAddNodesNone(t *testing.T) {
|
||||||
sel := Doc().Root.Find("div.pvk-gutter").AddNodes()
|
sel := Doc().Root.Find("div.pvk-gutter").AddNodes()
|
||||||
if len(sel.Nodes) != 6 {
|
AssertLength(t, sel.Nodes, 6)
|
||||||
t.Errorf("Expected 6 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAndSelf(t *testing.T) {
|
func TestAndSelf(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".span12").Last().AndSelf()
|
sel := Doc().Root.Find(".span12").Last().AndSelf()
|
||||||
if len(sel.Nodes) != 2 {
|
AssertLength(t, sel.Nodes, 2)
|
||||||
t.Errorf("Expected 2 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,42 +6,32 @@ import (
|
|||||||
|
|
||||||
func TestFilter(t *testing.T) {
|
func TestFilter(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".span12").Filter(".alert")
|
sel := Doc().Root.Find(".span12").Filter(".alert")
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterNone(t *testing.T) {
|
func TestFilterNone(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".span12").Filter(".zzalert")
|
sel := Doc().Root.Find(".span12").Filter(".zzalert")
|
||||||
if sel.Nodes != nil {
|
AssertLength(t, sel.Nodes, 0)
|
||||||
t.Error("Expected no node (nil), found some.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterFunction(t *testing.T) {
|
func TestFilterFunction(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").FilterFunction(func(i int, s *Selection) bool {
|
sel := Doc().Root.Find(".pvk-content").FilterFunction(func(i int, s *Selection) bool {
|
||||||
return i > 0
|
return i > 0
|
||||||
})
|
})
|
||||||
if len(sel.Nodes) != 2 {
|
AssertLength(t, sel.Nodes, 2)
|
||||||
t.Errorf("Expected 2 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterNode(t *testing.T) {
|
func TestFilterNode(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content")
|
sel := Doc().Root.Find(".pvk-content")
|
||||||
sel2 := sel.FilterNodes(sel.Nodes[2])
|
sel2 := sel.FilterNodes(sel.Nodes[2])
|
||||||
if len(sel2.Nodes) != 1 {
|
AssertLength(t, sel2.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel2.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterSelection(t *testing.T) {
|
func TestFilterSelection(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".link")
|
sel := Doc().Root.Find(".link")
|
||||||
sel2 := Doc().Root.Find("a[ng-click]")
|
sel2 := Doc().Root.Find("a[ng-click]")
|
||||||
sel3 := sel.FilterSelection(sel2)
|
sel3 := sel.FilterSelection(sel2)
|
||||||
if len(sel3.Nodes) != 1 {
|
AssertLength(t, sel3.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel3.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterSelectionNil(t *testing.T) {
|
func TestFilterSelectionNil(t *testing.T) {
|
||||||
@@ -49,64 +39,48 @@ func TestFilterSelectionNil(t *testing.T) {
|
|||||||
|
|
||||||
sel := Doc().Root.Find(".link")
|
sel := Doc().Root.Find(".link")
|
||||||
sel3 := sel.FilterSelection(sel2)
|
sel3 := sel.FilterSelection(sel2)
|
||||||
if len(sel3.Nodes) != 0 {
|
AssertLength(t, sel3.Nodes, 0)
|
||||||
t.Errorf("Expected no node, found %v.", len(sel3.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNot(t *testing.T) {
|
func TestNot(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".span12").Not(".alert")
|
sel := Doc().Root.Find(".span12").Not(".alert")
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNotNone(t *testing.T) {
|
func TestNotNone(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".span12").Not(".zzalert")
|
sel := Doc().Root.Find(".span12").Not(".zzalert")
|
||||||
if len(sel.Nodes) != 2 {
|
AssertLength(t, sel.Nodes, 2)
|
||||||
t.Errorf("Expected 2 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNotFunction(t *testing.T) {
|
func TestNotFunction(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").NotFunction(func(i int, s *Selection) bool {
|
sel := Doc().Root.Find(".pvk-content").NotFunction(func(i int, s *Selection) bool {
|
||||||
return i > 0
|
return i > 0
|
||||||
})
|
})
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNotNode(t *testing.T) {
|
func TestNotNode(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content")
|
sel := Doc().Root.Find(".pvk-content")
|
||||||
sel2 := sel.NotNodes(sel.Nodes[2])
|
sel2 := sel.NotNodes(sel.Nodes[2])
|
||||||
if len(sel2.Nodes) != 2 {
|
AssertLength(t, sel2.Nodes, 2)
|
||||||
t.Errorf("Expected 2 nodes, found %v.", len(sel2.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNotSelection(t *testing.T) {
|
func TestNotSelection(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".link")
|
sel := Doc().Root.Find(".link")
|
||||||
sel2 := Doc().Root.Find("a[ng-click]")
|
sel2 := Doc().Root.Find("a[ng-click]")
|
||||||
sel3 := sel.NotSelection(sel2)
|
sel3 := sel.NotSelection(sel2)
|
||||||
if len(sel3.Nodes) != 6 {
|
AssertLength(t, sel3.Nodes, 6)
|
||||||
t.Errorf("Expected 6 nodes, found %v.", len(sel3.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIntersection(t *testing.T) {
|
func TestIntersection(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-gutter")
|
sel := Doc().Root.Find(".pvk-gutter")
|
||||||
sel2 := Doc().Root.Find("div").Intersection(sel)
|
sel2 := Doc().Root.Find("div").Intersection(sel)
|
||||||
if len(sel2.Nodes) != 6 {
|
AssertLength(t, sel2.Nodes, 6)
|
||||||
t.Errorf("Expected 6 nodes, found %v.", len(sel2.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHas(t *testing.T) {
|
func TestHas(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".container-fluid").Has(".center-content")
|
sel := Doc().Root.Find(".container-fluid").Has(".center-content")
|
||||||
if len(sel.Nodes) != 2 {
|
AssertLength(t, sel.Nodes, 2)
|
||||||
t.Errorf("Expected 2 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
// Has() returns the high-level .container-fluid div, and the one that is the immediate parent of center-content
|
// Has() returns the high-level .container-fluid div, and the one that is the immediate parent of center-content
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,9 +88,7 @@ func TestHasNodes(t *testing.T) {
|
|||||||
sel := Doc().Root.Find(".container-fluid")
|
sel := Doc().Root.Find(".container-fluid")
|
||||||
sel2 := Doc().Root.Find(".center-content")
|
sel2 := Doc().Root.Find(".center-content")
|
||||||
sel = sel.HasNodes(sel2.Nodes...)
|
sel = sel.HasNodes(sel2.Nodes...)
|
||||||
if len(sel.Nodes) != 2 {
|
AssertLength(t, sel.Nodes, 2)
|
||||||
t.Errorf("Expected 2 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
// Has() returns the high-level .container-fluid div, and the one that is the immediate parent of center-content
|
// Has() returns the high-level .container-fluid div, and the one that is the immediate parent of center-content
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,21 +96,15 @@ func TestHasSelection(t *testing.T) {
|
|||||||
sel := Doc().Root.Find("p")
|
sel := Doc().Root.Find("p")
|
||||||
sel2 := Doc().Root.Find("small")
|
sel2 := Doc().Root.Find("small")
|
||||||
sel = sel.HasSelection(sel2)
|
sel = sel.HasSelection(sel2)
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnd(t *testing.T) {
|
func TestEnd(t *testing.T) {
|
||||||
sel := Doc().Root.Find("p").Has("small").End()
|
sel := Doc().Root.Find("p").Has("small").End()
|
||||||
if len(sel.Nodes) != 4 {
|
AssertLength(t, sel.Nodes, 4)
|
||||||
t.Errorf("Expected 4 nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEndToTop(t *testing.T) {
|
func TestEndToTop(t *testing.T) {
|
||||||
sel := Doc().Root.Find("p").Has("small").End().End().End()
|
sel := Doc().Root.Find("p").Has("small").End().End().End()
|
||||||
if len(sel.Nodes) != 0 {
|
AssertLength(t, sel.Nodes, 0)
|
||||||
t.Errorf("Expected 0 node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ func TestEach(t *testing.T) {
|
|||||||
if cnt != 4 {
|
if cnt != 4 {
|
||||||
t.Errorf("Expected Each() to call function 4 times, got %v times.", cnt)
|
t.Errorf("Expected Each() to call function 4 times, got %v times.", cnt)
|
||||||
}
|
}
|
||||||
if len(sel.Nodes) != 6 {
|
AssertLength(t, sel.Nodes, 6)
|
||||||
t.Errorf("Expected 6 matching nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEachEmptySelection(t *testing.T) {
|
func TestEachEmptySelection(t *testing.T) {
|
||||||
@@ -32,9 +30,7 @@ func TestEachEmptySelection(t *testing.T) {
|
|||||||
t.Error("Expected Each() to not be called on empty Selection.")
|
t.Error("Expected Each() to not be called on empty Selection.")
|
||||||
}
|
}
|
||||||
sel2 := sel.Find("div")
|
sel2 := sel.Find("div")
|
||||||
if sel2.Nodes != nil {
|
AssertLength(t, sel2.Nodes, 0)
|
||||||
t.Error("Expected Find() on empty Selection to return an empty Selection.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
|
|||||||
82
traversal.go
82
traversal.go
@@ -27,7 +27,7 @@ func (this *Selection) FindSelection(sel *Selection) *Selection {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindSelection() gets the descendants of each element in the current
|
// FindNodes() gets the descendants of each element in the current
|
||||||
// Selection, filtered by some nodes. It returns a new Selection object
|
// Selection, filtered by some nodes. It returns a new Selection object
|
||||||
// containing these matched elements.
|
// containing these matched elements.
|
||||||
func (this *Selection) FindNodes(nodes ...*html.Node) *Selection {
|
func (this *Selection) FindNodes(nodes ...*html.Node) *Selection {
|
||||||
@@ -35,29 +35,12 @@ func (this *Selection) FindNodes(nodes ...*html.Node) *Selection {
|
|||||||
|
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
if sliceContains(this.Nodes, n) {
|
if sliceContains(this.Nodes, n) {
|
||||||
matches = appendWithoutDuplicates(matches, n)
|
matches = appendWithoutDuplicates(matches, []*html.Node{n})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pushStack(this, matches)
|
return pushStack(this, matches)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private internal implementation of the Find() methods
|
|
||||||
func findWithContext(selector string, nodes ...*html.Node) []*html.Node {
|
|
||||||
var matches []*html.Node
|
|
||||||
|
|
||||||
sel := cascadia.MustCompile(selector)
|
|
||||||
// Match the selector on each node
|
|
||||||
for _, n := range nodes {
|
|
||||||
// Go down one level, becausejQuery's Find() selects only within descendants
|
|
||||||
for _, c := range n.Child {
|
|
||||||
if c.Type == html.ElementNode {
|
|
||||||
matches = appendWithoutDuplicates(matches, sel.MatchAll(c))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contents() gets the children of each element in the Selection,
|
// Contents() gets the children of each element in the Selection,
|
||||||
// including text and comment nodes. It returns a new Selection object
|
// including text and comment nodes. It returns a new Selection object
|
||||||
// containing these elements.
|
// containing these elements.
|
||||||
@@ -97,6 +80,67 @@ func (this *Selection) ChildrenFiltered(selector string) *Selection {
|
|||||||
return pushStack(this, nodes)
|
return pushStack(this, nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parent() gets the parent of each element in the Selection. It returns a
|
||||||
|
// new Selection object containing the matched elements.
|
||||||
|
func (this *Selection) Parent() *Selection {
|
||||||
|
return pushStack(this, getParentNodes(this.Nodes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parent() gets the parent of each element in the Selection filtered by a
|
||||||
|
// selector. It returns a new Selection object containing the matched elements.
|
||||||
|
func (this *Selection) ParentFiltered(selector string) *Selection {
|
||||||
|
// Get the Parent() unfiltered
|
||||||
|
nodes := getParentNodes(this.Nodes)
|
||||||
|
// Create a temporary Selection to filter using winnow
|
||||||
|
sel := &Selection{nodes, this.document, nil}
|
||||||
|
// Filter based on selector
|
||||||
|
nodes = winnow(sel, selector, true)
|
||||||
|
return pushStack(this, nodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal implementation of parent nodes that return a raw slice of Nodes.
|
||||||
|
func getParentNodes(nodes []*html.Node) []*html.Node {
|
||||||
|
return mapNodes(nodes, func(i int, n *html.Node, _ *html.Node) []*html.Node {
|
||||||
|
if n.Parent != nil {
|
||||||
|
return []*html.Node{n.Parent}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal map function used by many traversing methods. Takes the source nodes
|
||||||
|
// to iterate on, the mapping function that returns an array of nodes, and a
|
||||||
|
// stop node used for the *Until methods. Returns an array of nodes mapped by
|
||||||
|
// calling the callback function once for each node in the source nodes.
|
||||||
|
func mapNodes(nodes []*html.Node, f func(int, *html.Node, *html.Node) []*html.Node, stopNode *html.Node) (result []*html.Node) {
|
||||||
|
|
||||||
|
for i, n := range nodes {
|
||||||
|
if vals := f(i, n, stopNode); len(vals) > 0 {
|
||||||
|
result = appendWithoutDuplicates(result, vals)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private internal implementation of the Find() methods
|
||||||
|
func findWithContext(selector string, nodes ...*html.Node) []*html.Node {
|
||||||
|
var matches []*html.Node
|
||||||
|
|
||||||
|
// TODO : Refactor to use mapNodes?
|
||||||
|
sel := cascadia.MustCompile(selector)
|
||||||
|
// Match the selector on each node
|
||||||
|
for _, n := range nodes {
|
||||||
|
// Go down one level, becausejQuery's Find() selects only within descendants
|
||||||
|
for _, c := range n.Child {
|
||||||
|
if c.Type == html.ElementNode {
|
||||||
|
matches = appendWithoutDuplicates(matches, sel.MatchAll(c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matches
|
||||||
|
}
|
||||||
|
|
||||||
// Return the child nodes of each node in the Selection object, without
|
// Return the child nodes of each node in the Selection object, without
|
||||||
// duplicates.
|
// duplicates.
|
||||||
func getSelectionChildren(s *Selection, elemOnly bool) (result []*html.Node) {
|
func getSelectionChildren(s *Selection, elemOnly bool) (result []*html.Node) {
|
||||||
|
|||||||
@@ -6,81 +6,61 @@ import (
|
|||||||
|
|
||||||
func TestFind(t *testing.T) {
|
func TestFind(t *testing.T) {
|
||||||
sel := Doc().Root.Find("div.row-fluid")
|
sel := Doc().Root.Find("div.row-fluid")
|
||||||
if sel.Nodes == nil || len(sel.Nodes) != 9 {
|
AssertLength(t, sel.Nodes, 9)
|
||||||
t.Errorf("Expected 9 matching nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindNotSelf(t *testing.T) {
|
func TestFindNotSelf(t *testing.T) {
|
||||||
sel := Doc().Root.Find("h1").Find("h1")
|
sel := Doc().Root.Find("h1").Find("h1")
|
||||||
if len(sel.Nodes) > 0 {
|
AssertLength(t, sel.Nodes, 0)
|
||||||
t.Errorf("Expected no node, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindInvalidSelector(t *testing.T) {
|
func TestFindInvalidSelector(t *testing.T) {
|
||||||
defer func() {
|
defer AssertPanic(t)
|
||||||
if e := recover(); e == nil {
|
|
||||||
t.Error("Expected panic due to invalid selector.")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
Doc().Root.Find(":+ ^")
|
Doc().Root.Find(":+ ^")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChainedFind(t *testing.T) {
|
func TestChainedFind(t *testing.T) {
|
||||||
sel := Doc().Root.Find("div.hero-unit").Find(".row-fluid")
|
sel := Doc().Root.Find("div.hero-unit").Find(".row-fluid")
|
||||||
if sel.Nodes == nil || len(sel.Nodes) != 4 {
|
AssertLength(t, sel.Nodes, 4)
|
||||||
t.Errorf("Expected 4 matching nodes, found %v.", len(sel.Nodes))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChildren(t *testing.T) {
|
func TestChildren(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").Children()
|
sel := Doc().Root.Find(".pvk-content").Children()
|
||||||
if len(sel.Nodes) != 5 {
|
AssertLength(t, sel.Nodes, 5)
|
||||||
t.Errorf("Expected 5 child nodes, got %v.", len(sel.Nodes))
|
|
||||||
for _, n := range sel.Nodes {
|
|
||||||
t.Logf("%+v", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContents(t *testing.T) {
|
func TestContents(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").Contents()
|
sel := Doc().Root.Find(".pvk-content").Contents()
|
||||||
if len(sel.Nodes) != 13 {
|
AssertLength(t, sel.Nodes, 13)
|
||||||
t.Errorf("Expected 13 child nodes, got %v.", len(sel.Nodes))
|
|
||||||
for _, n := range sel.Nodes {
|
|
||||||
t.Logf("%+v", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChildrenFiltered(t *testing.T) {
|
func TestChildrenFiltered(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").ChildrenFiltered(".hero-unit")
|
sel := Doc().Root.Find(".pvk-content").ChildrenFiltered(".hero-unit")
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 child nodes, got %v.", len(sel.Nodes))
|
|
||||||
for _, n := range sel.Nodes {
|
|
||||||
t.Logf("%+v", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContentsFiltered(t *testing.T) {
|
func TestContentsFiltered(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").ContentsFiltered(".hero-unit")
|
sel := Doc().Root.Find(".pvk-content").ContentsFiltered(".hero-unit")
|
||||||
if len(sel.Nodes) != 1 {
|
AssertLength(t, sel.Nodes, 1)
|
||||||
t.Errorf("Expected 1 child nodes, got %v.", len(sel.Nodes))
|
|
||||||
for _, n := range sel.Nodes {
|
|
||||||
t.Logf("%+v", n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChildrenFilteredNone(t *testing.T) {
|
func TestChildrenFilteredNone(t *testing.T) {
|
||||||
sel := Doc().Root.Find(".pvk-content").ChildrenFiltered("a.btn")
|
sel := Doc().Root.Find(".pvk-content").ChildrenFiltered("a.btn")
|
||||||
if len(sel.Nodes) != 0 {
|
AssertLength(t, sel.Nodes, 0)
|
||||||
t.Errorf("Expected 0 child node, got %v.", len(sel.Nodes))
|
|
||||||
for _, n := range sel.Nodes {
|
|
||||||
t.Logf("%+v", n)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParent(t *testing.T) {
|
||||||
|
sel := Doc().Root.Find(".container-fluid").Parent()
|
||||||
|
AssertLength(t, sel.Nodes, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParentBody(t *testing.T) {
|
||||||
|
sel := Doc().Root.Find("body").Parent()
|
||||||
|
AssertLength(t, sel.Nodes, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParentFiltered(t *testing.T) {
|
||||||
|
sel := Doc().Root.Find(".container-fluid").ParentFiltered(".hero-unit")
|
||||||
|
AssertLength(t, sel.Nodes, 1)
|
||||||
|
AssertClass(t, sel, "hero-unit")
|
||||||
}
|
}
|
||||||
|
|||||||
33
type_test.go
33
type_test.go
@@ -6,6 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Test helper functions and members
|
||||||
var doc *Document
|
var doc *Document
|
||||||
|
|
||||||
func Doc() *Document {
|
func Doc() *Document {
|
||||||
@@ -15,6 +16,27 @@ func Doc() *Document {
|
|||||||
return doc
|
return doc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AssertLength(t *testing.T, nodes []*html.Node, length int) {
|
||||||
|
if len(nodes) != length {
|
||||||
|
t.Errorf("Expected %i nodes, found %v.", length, len(nodes))
|
||||||
|
for i, n := range nodes {
|
||||||
|
t.Logf("Node %i: %+v.", i, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AssertClass(t *testing.T, sel *Selection, class string) {
|
||||||
|
if !sel.HasClass(class) {
|
||||||
|
t.Errorf("Expected node to have class %s.", class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AssertPanic(t *testing.T) {
|
||||||
|
if e := recover(); e == nil {
|
||||||
|
t.Error("Expected a panic.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func EnsureDocLoaded() {
|
func EnsureDocLoaded() {
|
||||||
if f, e := os.Open("./testdata/page.html"); e != nil {
|
if f, e := os.Open("./testdata/page.html"); e != nil {
|
||||||
panic(e.Error())
|
panic(e.Error())
|
||||||
@@ -28,17 +50,6 @@ func EnsureDocLoaded() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func printNode(n *html.Node, t *testing.T) {
|
|
||||||
t.Logf("Type: %v, Data: %v\n", n.Type, n.Data)
|
|
||||||
for _, c := range n.Child {
|
|
||||||
printNode(c, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPrintAll(t *testing.T) {
|
|
||||||
//printNode(Doc().Root, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewDocument(t *testing.T) {
|
func TestNewDocument(t *testing.T) {
|
||||||
if f, e := os.Open("./testdata/page.html"); e != nil {
|
if f, e := os.Open("./testdata/page.html"); e != nil {
|
||||||
t.Error(e.Error())
|
t.Error(e.Error())
|
||||||
|
|||||||
Reference in New Issue
Block a user