Skip to content

Commit

Permalink
Make html.Selection.map return []goja.Value instead of []string
Browse files Browse the repository at this point in the history
  • Loading branch information
oleiade committed Jun 9, 2022
1 parent c5fb815 commit b7df16c
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 11 deletions.
13 changes: 7 additions & 6 deletions js/modules/k6/html/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,21 +426,22 @@ func (s Selection) Is(v goja.Value) bool {
}

// Map implements ES5 Array.prototype.map
func (s Selection) Map(v goja.Value) []string {
func (s Selection) Map(v goja.Value) []goja.Value {
gojaFn, isFn := goja.AssertFunction(v)
if !isFn {
common.Throw(s.rt, errors.New("the argument to map() must be a function"))
}

fn := func(idx int, sel *goquery.Selection) string {
var values []goja.Value
s.sel.Each(func(idx int, sel *goquery.Selection) {
selection := &Selection{sel: sel, URL: s.URL, rt: s.rt}

if fnRes, fnErr := gojaFn(v, s.rt.ToValue(idx), s.rt.ToValue(selection)); fnErr == nil {
return fnRes.String()
values = append(values, fnRes)
}
return ""
}
})

return s.sel.Map(fn)
return values
}

func (s Selection) Slice(start int, def ...int) Selection {
Expand Down
64 changes: 59 additions & 5 deletions js/modules/k6/html/html_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ const testHTML = `
</body>
`

const testXML = `
<ListAllMyBucketsResult>
<Buckets>
<Bucket>
<CreationDate>myCreationDateTimestamp</CreationDate>
<Name>myBucketName</Name>
</Bucket>
</Buckets>
<Owner>
<DisplayName>string</DisplayName>
<ID>string</ID>
</Owner>
</ListAllMyBucketsResult>
`

func getTestModuleInstance(t testing.TB) (*goja.Runtime, *ModuleInstance) {
rt := goja.New()
rt.SetFieldNameMapper(common.FieldNameMapper{})
Expand Down Expand Up @@ -409,10 +424,12 @@ func TestParseHTML(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
v, err := rt.RunString(`doc.find("#select_multi option").map(function(idx, val) { return val.text() })`)
if assert.NoError(t, err) {
mapped, ok := v.Export().([]string)
mapped, ok := v.Export().([]goja.Value)
assert.True(t, ok)
assert.Equal(t, 3, len(mapped))
assert.Equal(t, []string{"option 1", "option 2", "option 3"}, mapped)
assert.Equal(t, "option 1", mapped[0].String())
assert.Equal(t, "option 2", mapped[1].String())
assert.Equal(t, "option 3", mapped[2].String())
}
})
t.Run("Invalid arg", func(t *testing.T) {
Expand All @@ -425,11 +442,48 @@ func TestParseHTML(t *testing.T) {
t.Run("Map with attr must return string", func(t *testing.T) {
v, err := rt.RunString(`doc.find("#select_multi").map(function(idx, val) { return val.attr("name") })`)
if assert.NoError(t, err) {
mapped, ok := v.Export().([]string)
mapped, ok := v.Export().([]goja.Value)
assert.True(t, ok)
assert.Equal(t, 1, len(mapped))
assert.Equal(t, []string{"select_multi"}, mapped)
}
assert.Equal(t, "select_multi", mapped[0].String())
}
})
t.Run("Valid XML", func(t *testing.T) {
rt := getTestRuntimeWithDoc(t, testXML)
testScript := `
const buckets = doc
.find('Buckets')
.children()
.map(function (idx, bucket) {
let bucketObj = {}
bucket.children().each(function (idx, elem) {
switch (elem.nodeName()) {
case 'name':
Object.assign(bucketObj, { name: elem.textContent() })
break
case 'creationdate':
Object.assign(bucketObj, { creationDate: elem.textContent() })
break
}
})
return bucketObj
});
if (buckets.length !== 1) {
throw new Error('Expected 2 buckets, got ' + buckets.length)
}
if (buckets[0].name !== 'myBucketName') {
throw new Error('Expected bucket name to be "myBucketName", got ' + buckets[0].name)
}
if (buckets[0].creationDate !== 'myCreationDateTimestamp') {
throw new Error('Expected bucket creation date to be "myCreationDateTimestamp", got ' + buckets[0].creationDate)
}
`

_, err := rt.RunString(testScript)
assert.NoError(t, err)
})
})
t.Run("Next", func(t *testing.T) {
Expand Down

0 comments on commit b7df16c

Please sign in to comment.