diff --git a/object_goslice.go b/object_goslice.go index 0c2b2322..47d392b9 100644 --- a/object_goslice.go +++ b/object_goslice.go @@ -187,7 +187,7 @@ func (o *objectGoSlice) hasOwnPropertyStr(name unistring.String) bool { if idx := strToIdx64(name); idx >= 0 { return idx < int64(len(*o.data)) } - return false + return name == "length" } func (o *objectGoSlice) defineOwnPropertyIdx(idx valueInt, descr PropertyDescriptor, throw bool) bool { diff --git a/object_goslice_reflect.go b/object_goslice_reflect.go index 658c65f9..9c9ea1f4 100644 --- a/object_goslice_reflect.go +++ b/object_goslice_reflect.go @@ -196,7 +196,7 @@ func (o *objectGoSliceReflect) setForeignIdx(idx valueInt, val, receiver Value, } func (o *objectGoSliceReflect) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) { - return o._setForeignStr(name, trueValIfPresent(o._hasStr(name)), val, receiver, throw) + return o._setForeignStr(name, trueValIfPresent(o.hasOwnPropertyStr(name)), val, receiver, throw) } func (o *objectGoSliceReflect) hasOwnPropertyIdx(idx valueInt) bool { @@ -204,7 +204,7 @@ func (o *objectGoSliceReflect) hasOwnPropertyIdx(idx valueInt) bool { } func (o *objectGoSliceReflect) hasOwnPropertyStr(name unistring.String) bool { - if o._hasStr(name) { + if o._hasStr(name) || name == "length" { return true } return o.objectGoReflect._has(name.String()) diff --git a/object_goslice_reflect_test.go b/object_goslice_reflect_test.go index 112996ec..424b3fe0 100644 --- a/object_goslice_reflect_test.go +++ b/object_goslice_reflect_test.go @@ -334,3 +334,43 @@ func TestGoSliceReflectPopNoPtr(t *testing.T) { t.Fatal(v) } } + +func TestGoSliceReflectLengthProperty(t *testing.T) { + vm := New() + vm.Set("s", []int{2, 3, 4}) + _, err := vm.RunString(` + if (!s.hasOwnProperty("length")) { + throw new Error("hasOwnProperty() returned false"); + } + let desc = Object.getOwnPropertyDescriptor(s, "length"); + if (desc.value !== 3 || !desc.writable || desc.enumerable || desc.configurable) { + throw new Error("incorrect property descriptor: " + JSON.stringify(desc)); + } + `) + if err != nil { + t.Fatal(err) + } +} + +type testCustomSliceWithMethods []int + +func (a testCustomSliceWithMethods) Method() bool { + return true +} + +func TestGoSliceReflectMethods(t *testing.T) { + vm := New() + vm.Set("s", testCustomSliceWithMethods{1, 2, 3}) + _, err := vm.RunString(` + if (!s.hasOwnProperty("Method")) { + throw new Error("hasOwnProperty() returned false"); + } + let desc = Object.getOwnPropertyDescriptor(s, "Method"); + if (desc.value() !== true || desc.writable || !desc.enumerable || desc.configurable) { + throw new Error("incorrect property descriptor: " + JSON.stringify(desc)); + } + `) + if err != nil { + t.Fatal(err) + } +} diff --git a/object_goslice_test.go b/object_goslice_test.go index 1c23cb27..f83471fe 100644 --- a/object_goslice_test.go +++ b/object_goslice_test.go @@ -229,3 +229,20 @@ func TestGoSliceShift(t *testing.T) { t.Fatal(v) } } + +func TestGoSliceLengthProperty(t *testing.T) { + vm := New() + vm.Set("s", []interface{}{2, 3, 4}) + _, err := vm.RunString(` + if (!s.hasOwnProperty("length")) { + throw new Error("hasOwnProperty() returned false"); + } + let desc = Object.getOwnPropertyDescriptor(s, "length"); + if (desc.value !== 3 || !desc.writable || desc.enumerable || desc.configurable) { + throw new Error("incorrect property descriptor: " + JSON.stringify(desc)); + } + `) + if err != nil { + t.Fatal(err) + } +}