add NextFilteredUntil...() with tests

This commit is contained in:
Martin Angers
2012-09-10 09:09:32 -04:00
parent ab7dea3da3
commit 2fc9009621
5 changed files with 104 additions and 74 deletions
+1 -1
View File
@@ -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?
+14 -6
View File
@@ -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>
+26
View File
@@ -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
View File
@@ -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
View File
@@ -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())