mirror of
https://github.com/PuerkitoBio/goquery.git
synced 2026-10-21 04:47:41 +00:00
add NextFilteredUntil...() with tests
This commit is contained in:
@@ -78,7 +78,7 @@ Taken from example_test.go:
|
||||
|
||||
## TODOs
|
||||
|
||||
* Implement NextFilteredUntil...() and PrevFilteredUntil...().
|
||||
* Implement PrevFilteredUntil...().
|
||||
* Refactor Next...() and Prev...() to use the new NextSibling/PrevSibling fields.
|
||||
* Benchmarks so that future changes have a baseline to compare to.
|
||||
* Add jQuery's `Closest()`? Other missing functions?
|
||||
|
||||
Vendored
+14
-6
@@ -5,12 +5,20 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<div id="n1" class="even row"></div>
|
||||
<div id="n2" class="odd row"></div>
|
||||
<div id="n3" class="even row"></div>
|
||||
<div id="n4" class="odd row"></div>
|
||||
<div id="n5" class="even row"></div>
|
||||
<div id="n6" class="odd row"></div>
|
||||
<div id="n1" class="one even row"></div>
|
||||
<div id="n2" class="two odd row"></div>
|
||||
<div id="n3" class="three even row"></div>
|
||||
<div id="n4" class="four odd row"></div>
|
||||
<div id="n5" class="five even row"></div>
|
||||
<div id="n6" class="six odd row"></div>
|
||||
</div>
|
||||
<div id="foot">
|
||||
<div id="nf1" class="one even row"></div>
|
||||
<div id="nf2" class="two odd row"></div>
|
||||
<div id="nf3" class="three even row"></div>
|
||||
<div id="nf4" class="four odd row"></div>
|
||||
<div id="nf5" class="five even row"></div>
|
||||
<div id="nf6" class="six odd row"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -272,6 +272,32 @@ func (this *Selection) PrevUntilNodes(nodes ...*html.Node) *Selection {
|
||||
"", nodes))
|
||||
}
|
||||
|
||||
// NextFilteredUntil() is like NextUntil(), with the option to filter
|
||||
// the results based on a selector string.
|
||||
// It returns a new Selection object containing the matched elements.
|
||||
func (this *Selection) NextFilteredUntil(filterSelector string, untilSelector string) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingNextUntil,
|
||||
untilSelector, nil), filterSelector)
|
||||
}
|
||||
|
||||
// NextFilteredUntilSelection() is like NextUntilSelection(), with the
|
||||
// option to filter the results based on a selector string. It returns a new
|
||||
// Selection object containing the matched elements.
|
||||
func (this *Selection) NextFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
|
||||
if sel == nil {
|
||||
return this.NextFiltered(filterSelector)
|
||||
}
|
||||
return this.NextFilteredUntilNodes(filterSelector, sel.Nodes...)
|
||||
}
|
||||
|
||||
// NextFilteredUntilNodes() is like NextUntilNodes(), with the
|
||||
// option to filter the results based on a selector string. It returns a new
|
||||
// Selection object containing the matched elements.
|
||||
func (this *Selection) NextFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
|
||||
return filterAndPush(this, getSiblingNodes(this.Nodes, siblingNextUntil,
|
||||
"", nodes), filterSelector)
|
||||
}
|
||||
|
||||
// Filter and push filters the nodes based on a selector, and pushes the results
|
||||
// on the stack, with the srcSel as previous selection.
|
||||
func filterAndPush(srcSel *Selection, nodes []*html.Node, selector string) *Selection {
|
||||
|
||||
+54
-66
@@ -115,24 +115,7 @@ func TestParents(t *testing.T) {
|
||||
func TestParentsOrder(t *testing.T) {
|
||||
sel := Doc().Root.Find("#cf2").Parents()
|
||||
AssertLength(t, sel.Nodes, 6)
|
||||
if !sel.Eq(0).HasClass("hero-unit") {
|
||||
t.Errorf("Element at 0 should be hero-unit, found %+v.", sel.Get(0))
|
||||
}
|
||||
if !sel.Eq(1).HasClass("pvk-content") {
|
||||
t.Errorf("Element at 1 should be pvk-content, found %+v.", sel.Get(1))
|
||||
}
|
||||
if !sel.Eq(2).Is("div.row-fluid") {
|
||||
t.Errorf("Element at 2 should be row-fluid, found %+v.", sel.Get(2))
|
||||
}
|
||||
if !sel.Eq(3).Is("#cf1") {
|
||||
t.Errorf("Element at 3 should be cf1, found %+v.", sel.Get(3))
|
||||
}
|
||||
if !sel.Eq(4).Is("body") {
|
||||
t.Errorf("Element at 4 should be body, found %+v.", sel.Get(4))
|
||||
}
|
||||
if !sel.Eq(5).Is("html") {
|
||||
t.Errorf("Element at 5 should be html, found %+v.", sel.Get(5))
|
||||
}
|
||||
AssertSelectionIs(t, sel, ".hero-unit", ".pvk-content", "div.row-fluid", "#cf1", "body", "html")
|
||||
}
|
||||
|
||||
func TestParentsRollback(t *testing.T) {
|
||||
@@ -377,12 +360,7 @@ func TestPrevAll(t *testing.T) {
|
||||
func TestPrevAllOrder(t *testing.T) {
|
||||
sel := Doc().Root.Find("[ng-view]").PrevAll()
|
||||
AssertLength(t, sel.Nodes, 2)
|
||||
if !sel.Eq(0).Is("#cf4") {
|
||||
t.Errorf("Element at 0 should be cf4, found %+v.", sel.Get(0))
|
||||
}
|
||||
if !sel.Eq(1).Is("#cf3") {
|
||||
t.Errorf("Element at 1 should be cf3, found %+v.", sel.Get(1))
|
||||
}
|
||||
AssertSelectionIs(t, sel, "#cf4", "#cf3")
|
||||
}
|
||||
|
||||
func TestPrevAllRollback(t *testing.T) {
|
||||
@@ -410,28 +388,19 @@ func TestPrevAllFilteredRollback(t *testing.T) {
|
||||
func TestNextUntil(t *testing.T) {
|
||||
sel := Doc().Root.Find(".alert a").NextUntil("p")
|
||||
AssertLength(t, sel.Nodes, 1)
|
||||
if !sel.Eq(0).Is("h4") {
|
||||
t.Errorf("Expected node 0 to be h4, found %+v.", sel.Get(0))
|
||||
}
|
||||
AssertSelectionIs(t, sel, "h4")
|
||||
}
|
||||
|
||||
func TestNextUntil2(t *testing.T) {
|
||||
sel := Doc().Root.Find("#cf2-1").NextUntil("[ng-cloak]")
|
||||
AssertLength(t, sel.Nodes, 1)
|
||||
if !sel.Eq(0).Is("#cf2-2") {
|
||||
t.Errorf("Expected node 0 to be cf2-2, found %+v.", sel.Get(0))
|
||||
}
|
||||
AssertSelectionIs(t, sel, "#cf2-2")
|
||||
}
|
||||
|
||||
func TestNextUntilOrder(t *testing.T) {
|
||||
sel := Doc().Root.Find("#cf2-1").NextUntil("#cf2-4")
|
||||
AssertLength(t, sel.Nodes, 2)
|
||||
if !sel.Eq(0).Is("#cf2-2") {
|
||||
t.Errorf("Expected node 0 to be cf2-2, found %+v.", sel.Get(0))
|
||||
}
|
||||
if !sel.Eq(1).Is("#cf2-3") {
|
||||
t.Errorf("Expected node 1 to be cf2-3, found %+v.", sel.Get(1))
|
||||
}
|
||||
AssertSelectionIs(t, sel, "#cf2-2", "#cf2-3")
|
||||
}
|
||||
|
||||
func TestNextUntilRollback(t *testing.T) {
|
||||
@@ -445,9 +414,7 @@ func TestNextUntilSelection(t *testing.T) {
|
||||
sel2 := Doc2().Root.Find("#n4")
|
||||
sel2 = sel.NextUntilSelection(sel2)
|
||||
AssertLength(t, sel2.Nodes, 1)
|
||||
if !sel2.Eq(0).Is("#n3") {
|
||||
t.Errorf("Expected node 0 to be n3, found %+v.", sel2.Get(0))
|
||||
}
|
||||
AssertSelectionIs(t, sel2, "#n3")
|
||||
}
|
||||
|
||||
func TestNextUntilSelectionRollback(t *testing.T) {
|
||||
@@ -462,12 +429,7 @@ func TestNextUntilNodes(t *testing.T) {
|
||||
sel2 := Doc2().Root.Find("#n5")
|
||||
sel2 = sel.NextUntilNodes(sel2.Nodes...)
|
||||
AssertLength(t, sel2.Nodes, 2)
|
||||
if !sel2.Eq(0).Is("#n3") {
|
||||
t.Errorf("Expected node 0 to be n3, found %+v.", sel2.Get(0))
|
||||
}
|
||||
if !sel2.Eq(1).Is("#n4") {
|
||||
t.Errorf("Expected node 1 to be n4, found %+v.", sel2.Get(1))
|
||||
}
|
||||
AssertSelectionIs(t, sel2, "#n3", "#n4")
|
||||
}
|
||||
|
||||
func TestNextUntilNodesRollback(t *testing.T) {
|
||||
@@ -480,28 +442,19 @@ func TestNextUntilNodesRollback(t *testing.T) {
|
||||
func TestPrevUntil(t *testing.T) {
|
||||
sel := Doc().Root.Find(".alert p").PrevUntil("a")
|
||||
AssertLength(t, sel.Nodes, 1)
|
||||
if !sel.Eq(0).Is("h4") {
|
||||
t.Errorf("Expected node 0 to be h4, found %+v.", sel.Get(0))
|
||||
}
|
||||
AssertSelectionIs(t, sel, "h4")
|
||||
}
|
||||
|
||||
func TestPrevUntil2(t *testing.T) {
|
||||
sel := Doc().Root.Find("[ng-cloak]").PrevUntil(":not([ng-cloak])")
|
||||
AssertLength(t, sel.Nodes, 1)
|
||||
if !sel.Eq(0).Is("[ng-cloak]") {
|
||||
t.Errorf("Expected node 0 to be [ng-cloak], found %+v.", sel.Get(0))
|
||||
}
|
||||
AssertSelectionIs(t, sel, "[ng-cloak]")
|
||||
}
|
||||
|
||||
func TestPrevUntilOrder(t *testing.T) {
|
||||
sel := Doc().Root.Find("#cf2-4").PrevUntil("#cf2-1")
|
||||
AssertLength(t, sel.Nodes, 2)
|
||||
if !sel.Eq(0).Is("#cf2-3") {
|
||||
t.Errorf("Expected node 0 to be cf2-3, found %+v.", sel.Get(0))
|
||||
}
|
||||
if !sel.Eq(1).Is("#cf2-2") {
|
||||
t.Errorf("Expected node 1 to be cf2-2, found %+v.", sel.Get(1))
|
||||
}
|
||||
AssertSelectionIs(t, sel, "#cf2-3", "#cf2-2")
|
||||
}
|
||||
|
||||
func TestPrevUntilRollback(t *testing.T) {
|
||||
@@ -515,9 +468,7 @@ func TestPrevUntilSelection(t *testing.T) {
|
||||
sel2 := Doc2().Root.Find("#n2")
|
||||
sel2 = sel.PrevUntilSelection(sel2)
|
||||
AssertLength(t, sel2.Nodes, 1)
|
||||
if !sel2.Eq(0).Is("#n3") {
|
||||
t.Errorf("Expected node 0 to be n3, found %+v.", sel2.Get(0))
|
||||
}
|
||||
AssertSelectionIs(t, sel2, "#n3")
|
||||
}
|
||||
|
||||
func TestPrevUntilSelectionRollback(t *testing.T) {
|
||||
@@ -532,12 +483,7 @@ func TestPrevUntilNodes(t *testing.T) {
|
||||
sel2 := Doc2().Root.Find("#n2")
|
||||
sel2 = sel.PrevUntilNodes(sel2.Nodes...)
|
||||
AssertLength(t, sel2.Nodes, 2)
|
||||
if !sel2.Eq(0).Is("#n4") {
|
||||
t.Errorf("Expected node 0 to be n4, found %+v.", sel2.Get(0))
|
||||
}
|
||||
if !sel2.Eq(1).Is("#n3") {
|
||||
t.Errorf("Expected node 1 to be n3, found %+v.", sel2.Get(1))
|
||||
}
|
||||
AssertSelectionIs(t, sel2, "#n4", "#n3")
|
||||
}
|
||||
|
||||
func TestPrevUntilNodesRollback(t *testing.T) {
|
||||
@@ -546,3 +492,45 @@ func TestPrevUntilNodesRollback(t *testing.T) {
|
||||
sel2 = sel.PrevUntilNodes(sel2.Nodes...).End()
|
||||
AssertEqual(t, sel, sel2)
|
||||
}
|
||||
|
||||
func TestNextFilteredUntil(t *testing.T) {
|
||||
sel := Doc2().Root.Find(".two").NextFilteredUntil(".even", ".six")
|
||||
AssertLength(t, sel.Nodes, 4)
|
||||
AssertSelectionIs(t, sel, "#n3", "#n5", "#nf3", "#nf5")
|
||||
}
|
||||
|
||||
func TestNextFilteredUntilRollback(t *testing.T) {
|
||||
sel := Doc2().Root.Find(".two")
|
||||
sel2 := sel.NextFilteredUntil(".even", ".six").End()
|
||||
AssertEqual(t, sel, sel2)
|
||||
}
|
||||
|
||||
func TestNextFilteredUntilSelection(t *testing.T) {
|
||||
sel := Doc2().Root.Find(".even")
|
||||
sel2 := Doc2().Root.Find(".five")
|
||||
sel = sel.NextFilteredUntilSelection(".even", sel2)
|
||||
AssertLength(t, sel.Nodes, 2)
|
||||
AssertSelectionIs(t, sel, "#n3", "#nf3")
|
||||
}
|
||||
|
||||
func TestNextFilteredUntilSelectionRollback(t *testing.T) {
|
||||
sel := Doc2().Root.Find(".even")
|
||||
sel2 := Doc2().Root.Find(".five")
|
||||
sel3 := sel.NextFilteredUntilSelection(".even", sel2).End()
|
||||
AssertEqual(t, sel, sel3)
|
||||
}
|
||||
|
||||
func TestNextFilteredUntilNodes(t *testing.T) {
|
||||
sel := Doc2().Root.Find(".even")
|
||||
sel2 := Doc2().Root.Find(".four")
|
||||
sel = sel.NextFilteredUntilNodes(".odd", sel2.Nodes...)
|
||||
AssertLength(t, sel.Nodes, 4)
|
||||
AssertSelectionIs(t, sel, "#n2", "#n6", "#nf2", "#nf6")
|
||||
}
|
||||
|
||||
func TestNextFilteredUntilNodesRollback(t *testing.T) {
|
||||
sel := Doc2().Root.Find(".even")
|
||||
sel2 := Doc2().Root.Find(".four")
|
||||
sel3 := sel.NextFilteredUntilNodes(".odd", sel2.Nodes...).End()
|
||||
AssertEqual(t, sel, sel3)
|
||||
}
|
||||
|
||||
+9
-1
@@ -35,7 +35,7 @@ func AssertLength(t *testing.T, nodes []*html.Node, length int) {
|
||||
|
||||
func AssertClass(t *testing.T, sel *Selection, class string) {
|
||||
if !sel.HasClass(class) {
|
||||
t.Errorf("Expected node to have class %s.", class)
|
||||
t.Errorf("Expected node to have class %s, found %+v.", class, sel.Get(0))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,14 @@ func AssertEqual(t *testing.T, s1 *Selection, s2 *Selection) {
|
||||
}
|
||||
}
|
||||
|
||||
func AssertSelectionIs(t *testing.T, sel *Selection, is ...string) {
|
||||
for i := 0; i < sel.Length(); i++ {
|
||||
if !sel.Eq(i).Is(is[i]) {
|
||||
t.Errorf("Expected node %d to be %s, found %+v", i, is[i], sel.Get(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func LoadDoc(page string) *Document {
|
||||
if f, e := os.Open(fmt.Sprintf("./testdata/%s", page)); e != nil {
|
||||
panic(e.Error())
|
||||
|
||||
Reference in New Issue
Block a user