Skip to content

Commit

Permalink
Merge pull request gocolly#205 from vosmith/unmarshal_pointer_slices
Browse files Browse the repository at this point in the history
Support umarshalling slices of pointers
  • Loading branch information
asciimoo authored Aug 10, 2018
2 parents 0f78ed3 + 6024780 commit 021b828
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
6 changes: 6 additions & 0 deletions unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ func unmarshalSlice(s *goquery.Selection, selector, htmlAttr string, attrV refle
val := getDOMValue(s, htmlAttr)
attrV.Set(reflect.Append(attrV, reflect.Indirect(reflect.ValueOf(val))))
})
case reflect.Ptr:
s.Find(selector).Each(func(_ int, innerSel *goquery.Selection) {
someVal := reflect.New(attrV.Type().Elem().Elem())
UnmarshalHTML(someVal.Interface(), innerSel)
attrV.Set(reflect.Append(attrV, someVal))
})
default:
return errors.New("Invalid slice type")
}
Expand Down
29 changes: 29 additions & 0 deletions unmarshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

var basicTestData = []byte(`<ul><li class="x">list <span>item</span> 1</li><li>list item 2</li><li>3</li></ul>`)
var nestedTestData = []byte(`<div><p>a</p><div><p>b</p><div><p>c</p></div></div></div>`)
var pointerSliceTestData = []byte(`<ul class="object"><li class="info">Information: <span>Info 1</span></li><li class="info">Information: <span>Info 2</span></li></ul>`)

func TestBasicUnmarshal(t *testing.T) {
doc, _ := goquery.NewDocumentFromReader(bytes.NewBuffer(basicTestData))
Expand Down Expand Up @@ -70,3 +71,31 @@ func TestNestedUnmarshal(t *testing.T) {
t.Errorf(`Invalid data for Struct.Struct.String: %q, expected "c"`, s.Struct.Struct.String)
}
}

func TestPointerSliceUnmarshall(t *testing.T) {
type info struct {
Text string `selector:"span"`
}
type object struct {
Info []*info `selector:"li.info"`
}

doc, _ := goquery.NewDocumentFromReader(bytes.NewBuffer(pointerSliceTestData))
e := HTMLElement{DOM: doc.First()}
o := object{}
err := e.Unmarshal(&o)
if err != nil {
t.Fatalf("Failed to unmarshal page: %s\n", err.Error())
}

if len(o.Info) != 2 {
t.Errorf("Invalid length for Info: %d, expected 2", len(o.Info))
}
if o.Info[0].Text != "Info 1" {
t.Errorf("Invalid data for Info.[0].Text: %s, expected Info 1", o.Info[0].Text)
}
if o.Info[1].Text != "Info 2" {
t.Errorf("Invalid data for Info.[1].Text: %s, expected Info 2", o.Info[1].Text)
}

}

0 comments on commit 021b828

Please sign in to comment.