From 98eb88c22ba874d211d1684d4cf1c74c8bf9b33c Mon Sep 17 00:00:00 2001 From: Anthony Gedeon Date: Sun, 24 Oct 2021 21:08:06 -0500 Subject: [PATCH 1/3] Fixes PuerkitoBio#377, renders the html that can be manipulated with an writer as input --- utilities.go | 21 +++++++---- utilities_test.go | 91 +++++++++++++++++++++++++++-------------------- 2 files changed, 67 insertions(+), 45 deletions(-) diff --git a/utilities.go b/utilities.go index 3e11b1d..d4a1b50 100644 --- a/utilities.go +++ b/utilities.go @@ -2,6 +2,7 @@ package goquery import ( "bytes" + "io" "golang.org/x/net/html" ) @@ -57,6 +58,19 @@ func nodeName(node *html.Node) string { } } +// Render renders the html of the first element from selector and writes it to the writer. +// It behaves similar to OuterHtml but takes io.Writer as input. +func Render(w io.Writer, s *Selection) error { + if s.Length() == 0 { + return nil + } + n := s.Get(0) + if err := html.Render(w, n); err != nil { + return err + } + return nil +} + // OuterHtml returns the outer HTML rendering of the first item in // the selection - that is, the HTML including the first element's // tag and attributes. @@ -66,12 +80,7 @@ func nodeName(node *html.Node) string { // a property provided by the DOM). func OuterHtml(s *Selection) (string, error) { var buf bytes.Buffer - - if s.Length() == 0 { - return "", nil - } - n := s.Get(0) - if err := html.Render(&buf, n); err != nil { + if err := Render(&buf, s); err != nil { return "", err } return buf.String(), nil diff --git a/utilities_test.go b/utilities_test.go index c8e9d54..88a468d 100644 --- a/utilities_test.go +++ b/utilities_test.go @@ -24,6 +24,49 @@ var allNodes = ` ` +func assertMatchNodes(t testing.TB, doc *Document) { + t.Helper() + + n0 := doc.Nodes[0] + nDT := n0.FirstChild + sMeta := doc.Find("meta") + sP := doc.Find("p") + nP := sP.Get(0) + nComment := nP.FirstChild + nText := nComment.NextSibling + sHeaders := doc.Find(".header") + + cases := []struct { + node *html.Node + sel *Selection + want string + }{ + {nDT, nil, ""}, // render makes DOCTYPE all caps + {nil, sMeta, ``}, // and auto-closes the meta + {nil, sP, `

+ This is some text. +

`}, + {nComment, nil, ""}, + {nText, nil, ` + This is some text. + `}, + {nil, sHeaders, `

`}, + } + for i, c := range cases { + if c.sel == nil { + c.sel = newSingleSelection(c.node, doc) + } + got, err := OuterHtml(c.sel) + if err != nil { + t.Fatal(err) + } + + if got != c.want { + t.Errorf("%d: want %q, got %q", i, c.want, got) + } + } +} + func TestNodeName(t *testing.T) { doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) if err != nil { @@ -81,48 +124,18 @@ func TestNodeNameMultiSel(t *testing.T) { } } +func TestRender(t *testing.T) { + doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) + if err != nil { + t.Fatal(err) + } + assertMatchNodes(t, doc) +} + func TestOuterHtml(t *testing.T) { doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) if err != nil { t.Fatal(err) } - - n0 := doc.Nodes[0] - nDT := n0.FirstChild - sMeta := doc.Find("meta") - sP := doc.Find("p") - nP := sP.Get(0) - nComment := nP.FirstChild - nText := nComment.NextSibling - sHeaders := doc.Find(".header") - - cases := []struct { - node *html.Node - sel *Selection - want string - }{ - {nDT, nil, ""}, // render makes DOCTYPE all caps - {nil, sMeta, ``}, // and auto-closes the meta - {nil, sP, `

- This is some text. -

`}, - {nComment, nil, ""}, - {nText, nil, ` - This is some text. - `}, - {nil, sHeaders, `

`}, - } - for i, c := range cases { - if c.sel == nil { - c.sel = newSingleSelection(c.node, doc) - } - got, err := OuterHtml(c.sel) - if err != nil { - t.Fatal(err) - } - - if got != c.want { - t.Errorf("%d: want %q, got %q", i, c.want, got) - } - } + assertMatchNodes(t, doc) } From 11e123345721c49d0aa1fa205de94025f34a9c59 Mon Sep 17 00:00:00 2001 From: Anthony Gedeon Date: Mon, 25 Oct 2021 18:16:09 -0500 Subject: [PATCH 2/3] fix(test): remove Render testcase since OuterHtml handles Render internally --- utilities_test.go | 92 ++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 53 deletions(-) diff --git a/utilities_test.go b/utilities_test.go index 88a468d..deaf34e 100644 --- a/utilities_test.go +++ b/utilities_test.go @@ -24,49 +24,6 @@ var allNodes = ` ` -func assertMatchNodes(t testing.TB, doc *Document) { - t.Helper() - - n0 := doc.Nodes[0] - nDT := n0.FirstChild - sMeta := doc.Find("meta") - sP := doc.Find("p") - nP := sP.Get(0) - nComment := nP.FirstChild - nText := nComment.NextSibling - sHeaders := doc.Find(".header") - - cases := []struct { - node *html.Node - sel *Selection - want string - }{ - {nDT, nil, ""}, // render makes DOCTYPE all caps - {nil, sMeta, ``}, // and auto-closes the meta - {nil, sP, `

- This is some text. -

`}, - {nComment, nil, ""}, - {nText, nil, ` - This is some text. - `}, - {nil, sHeaders, `

`}, - } - for i, c := range cases { - if c.sel == nil { - c.sel = newSingleSelection(c.node, doc) - } - got, err := OuterHtml(c.sel) - if err != nil { - t.Fatal(err) - } - - if got != c.want { - t.Errorf("%d: want %q, got %q", i, c.want, got) - } - } -} - func TestNodeName(t *testing.T) { doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) if err != nil { @@ -123,19 +80,48 @@ func TestNodeNameMultiSel(t *testing.T) { t.Errorf("want %v, got %v", in, out) } } - -func TestRender(t *testing.T) { - doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) - if err != nil { - t.Fatal(err) - } - assertMatchNodes(t, doc) -} - func TestOuterHtml(t *testing.T) { doc, err := NewDocumentFromReader(strings.NewReader(allNodes)) if err != nil { t.Fatal(err) } - assertMatchNodes(t, doc) + + n0 := doc.Nodes[0] + nDT := n0.FirstChild + sMeta := doc.Find("meta") + sP := doc.Find("p") + nP := sP.Get(0) + nComment := nP.FirstChild + nText := nComment.NextSibling + sHeaders := doc.Find(".header") + + cases := []struct { + node *html.Node + sel *Selection + want string + }{ + {nDT, nil, ""}, // render makes DOCTYPE all caps + {nil, sMeta, ``}, // and auto-closes the meta + {nil, sP, `

+ This is some text. +

`}, + {nComment, nil, ""}, + {nText, nil, ` + This is some text. + `}, + {nil, sHeaders, `

`}, + } + for i, c := range cases { + if c.sel == nil { + c.sel = newSingleSelection(c.node, doc) + } + got, err := OuterHtml(c.sel) + if err != nil { + t.Fatal(err) + } + + if got != c.want { + t.Errorf("%d: want %q, got %q", i, c.want, got) + } + } } From d35d4cec3eba112ffe3ea03e665e1fcd1bdf9a94 Mon Sep 17 00:00:00 2001 From: Anthony Gedeon Date: Mon, 25 Oct 2021 18:16:30 -0500 Subject: [PATCH 3/3] fix(doc): update docs for accurate representation of function --- utilities.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/utilities.go b/utilities.go index d4a1b50..656cf01 100644 --- a/utilities.go +++ b/utilities.go @@ -59,16 +59,13 @@ func nodeName(node *html.Node) string { } // Render renders the html of the first element from selector and writes it to the writer. -// It behaves similar to OuterHtml but takes io.Writer as input. +// // It behaves the same as OuterHtml but writes to w instead of returning the string. func Render(w io.Writer, s *Selection) error { if s.Length() == 0 { return nil } n := s.Get(0) - if err := html.Render(w, n); err != nil { - return err - } - return nil + return html.Render(w, n) } // OuterHtml returns the outer HTML rendering of the first item in