From d5e9341ca11e38de25adb74ed32d0da784b13f7a Mon Sep 17 00:00:00 2001 From: Martin Angers Date: Mon, 10 Sep 2012 10:04:00 -0400 Subject: [PATCH] add PrevFilteredUntil...() with tests --- README.md | 3 +-- traversal.go | 26 ++++++++++++++++++++++++++ traversal_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7d9ae19..fb7d064 100644 --- a/README.md +++ b/README.md @@ -78,9 +78,8 @@ Taken from example_test.go: ## TODOs -* Implement PrevFilteredUntil...(). -* Refactor Next...() and Prev...() to use the new NextSibling/PrevSibling fields. * Benchmarks so that future changes have a baseline to compare to. +* Refactor Next...() and Prev...() to use the new NextSibling/PrevSibling fields. * Add jQuery's `Closest()`? Other missing functions? * Support negative indices in `Slice()`, like jQuery. diff --git a/traversal.go b/traversal.go index 32b99a7..825ea78 100644 --- a/traversal.go +++ b/traversal.go @@ -298,6 +298,32 @@ func (this *Selection) NextFilteredUntilNodes(filterSelector string, nodes ...*h "", nodes), filterSelector) } +// PrevFilteredUntil() is like PrevUntil(), 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) PrevFilteredUntil(filterSelector string, untilSelector string) *Selection { + return filterAndPush(this, getSiblingNodes(this.Nodes, siblingPrevUntil, + untilSelector, nil), filterSelector) +} + +// PrevFilteredUntilSelection() is like PrevUntilSelection(), 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) PrevFilteredUntilSelection(filterSelector string, sel *Selection) *Selection { + if sel == nil { + return this.PrevFiltered(filterSelector) + } + return this.PrevFilteredUntilNodes(filterSelector, sel.Nodes...) +} + +// PrevFilteredUntilNodes() is like PrevUntilNodes(), 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) PrevFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection { + return filterAndPush(this, getSiblingNodes(this.Nodes, siblingPrevUntil, + "", 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 { diff --git a/traversal_test.go b/traversal_test.go index 553d6ab..fa678d9 100644 --- a/traversal_test.go +++ b/traversal_test.go @@ -534,3 +534,45 @@ func TestNextFilteredUntilNodesRollback(t *testing.T) { sel3 := sel.NextFilteredUntilNodes(".odd", sel2.Nodes...).End() AssertEqual(t, sel, sel3) } + +func TestPrevFilteredUntil(t *testing.T) { + sel := Doc2().Root.Find(".five").PrevFilteredUntil(".odd", ".one") + AssertLength(t, sel.Nodes, 4) + AssertSelectionIs(t, sel, "#n4", "#n2", "#nf4", "#nf2") +} + +func TestPrevFilteredUntilRollback(t *testing.T) { + sel := Doc2().Root.Find(".four") + sel2 := sel.PrevFilteredUntil(".odd", ".one").End() + AssertEqual(t, sel, sel2) +} + +func TestPrevFilteredUntilSelection(t *testing.T) { + sel := Doc2().Root.Find(".odd") + sel2 := Doc2().Root.Find(".two") + sel = sel.PrevFilteredUntilSelection(".odd", sel2) + AssertLength(t, sel.Nodes, 2) + AssertSelectionIs(t, sel, "#n4", "#nf4") +} + +func TestPrevFilteredUntilSelectionRollback(t *testing.T) { + sel := Doc2().Root.Find(".even") + sel2 := Doc2().Root.Find(".five") + sel3 := sel.PrevFilteredUntilSelection(".even", sel2).End() + AssertEqual(t, sel, sel3) +} + +func TestPrevFilteredUntilNodes(t *testing.T) { + sel := Doc2().Root.Find(".even") + sel2 := Doc2().Root.Find(".four") + sel = sel.PrevFilteredUntilNodes(".odd", sel2.Nodes...) + AssertLength(t, sel.Nodes, 2) + AssertSelectionIs(t, sel, "#n2", "#nf2") +} + +func TestPrevFilteredUntilNodesRollback(t *testing.T) { + sel := Doc2().Root.Find(".even") + sel2 := Doc2().Root.Find(".four") + sel3 := sel.PrevFilteredUntilNodes(".odd", sel2.Nodes...).End() + AssertEqual(t, sel, sel3) +}