diff --git a/README.md b/README.md index 9340382..2790f1b 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Taken from example_test.go: // remove the leading "x" before Output on the next line. This will cause the // example to fail (all the "real" tests should pass). - // xOutput: volutarily fail the Example output. + // xOutput: voluntarily fail the Example output. } diff --git a/example_test.go b/example_test.go index 97abe19..3867ca3 100644 --- a/example_test.go +++ b/example_test.go @@ -38,5 +38,5 @@ func ExampleScrape_MetalReview() { // remove the leading "x" before Output on the next line. This will cause the // example to fail (all the "real" tests should pass). - // xOutput: volutarily fail the Example output. + // xOutput: voluntarily fail the Example output. } diff --git a/property_test.go b/property_test.go index 8257ff6..80882cb 100644 --- a/property_test.go +++ b/property_test.go @@ -7,8 +7,6 @@ import ( ) func TestAttrExists(t *testing.T) { - EnsureDocLoaded() - if val, ok := Doc().Root.Find("a").Attr("href"); !ok { t.Error("Expected a value for the href attribute.") } else { diff --git a/testdata/page2.html b/testdata/page2.html new file mode 100644 index 0000000..66ea563 --- /dev/null +++ b/testdata/page2.html @@ -0,0 +1,16 @@ + + + + Tests for siblings + + +
+
+
+
+
+
+
+
+ + diff --git a/traversal.go b/traversal.go index 0a4e8ef..5b6ef49 100644 --- a/traversal.go +++ b/traversal.go @@ -228,6 +228,24 @@ func (this *Selection) PrevUntil(selector string) *Selection { selector, nil)) } +// PrevUntilSelection() gets all preceding siblings of each element up to but not +// including the element matched by the Selection. It returns a new Selection +// object containing the matched elements. +func (this *Selection) PrevUntilSelection(sel *Selection) *Selection { + if sel == nil { + return this.PrevAll() + } + return this.PrevUntilNodes(sel.Nodes...) +} + +// PrevUntilNodes() gets all preceding siblings of each element up to but not +// including the element matched by the nodes. It returns a new Selection +// object containing the matched elements. +func (this *Selection) PrevUntilNodes(nodes ...*html.Node) *Selection { + return pushStack(this, getSiblingNodes(this.Nodes, siblingPrevUntil, + "", nodes)) +} + // 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 a7c846e..00471da 100644 --- a/traversal_test.go +++ b/traversal_test.go @@ -439,3 +439,40 @@ func TestPrevUntilRollback(t *testing.T) { sel2 := sel.PrevUntil("#cf2-1").End() AssertEqual(t, sel, sel2) } + +func TestPrevUntilSelection(t *testing.T) { + sel := Doc2().Root.Find("#n4") + 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)) + } +} + +func TestPrevUntilSelectionRollback(t *testing.T) { + sel := Doc2().Root.Find("#n4") + sel2 := Doc2().Root.Find("#n2") + sel2 = sel.PrevUntilSelection(sel2).End() + AssertEqual(t, sel, sel2) +} + +func TestPrevUntilNodes(t *testing.T) { + sel := Doc2().Root.Find("#n5") + 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)) + } +} + +func TestPrevUntilNodesRollback(t *testing.T) { + sel := Doc2().Root.Find("#n5") + sel2 := Doc2().Root.Find("#n2") + sel2 = sel.PrevUntilNodes(sel2.Nodes...).End() + AssertEqual(t, sel, sel2) +} diff --git a/type_test.go b/type_test.go index da55224..336f9c1 100644 --- a/type_test.go +++ b/type_test.go @@ -2,19 +2,27 @@ package goquery import ( "exp/html" + "fmt" "os" "testing" ) // Test helper functions and members var doc *Document +var doc2 *Document func Doc() *Document { if doc == nil { - EnsureDocLoaded() + doc = LoadDoc("page.html") } return doc } +func Doc2() *Document { + if doc2 == nil { + doc2 = LoadDoc("page2.html") + } + return doc2 +} func AssertLength(t *testing.T, nodes []*html.Node, length int) { if len(nodes) != length { @@ -43,17 +51,18 @@ func AssertEqual(t *testing.T, s1 *Selection, s2 *Selection) { } } -func EnsureDocLoaded() { - if f, e := os.Open("./testdata/page.html"); e != nil { +func LoadDoc(page string) *Document { + if f, e := os.Open(fmt.Sprintf("./testdata/%s", page)); e != nil { panic(e.Error()) } else { defer f.Close() if node, e := html.Parse(f); e != nil { panic(e.Error()) } else { - doc = NewDocumentFromNode(node) + return NewDocumentFromNode(node) } } + return nil } func TestNewDocument(t *testing.T) {