Преглед на файлове

Report 'length' as own property for Go slices. Fixes #328.

Dmitry Panov преди 4 години
родител
ревизия
ac5354e9a8
променени са 4 файла, в които са добавени 60 реда и са изтрити 3 реда
  1. 1 1
      object_goslice.go
  2. 2 2
      object_goslice_reflect.go
  3. 40 0
      object_goslice_reflect_test.go
  4. 17 0
      object_goslice_test.go

+ 1 - 1
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 {

+ 2 - 2
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())

+ 40 - 0
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)
+	}
+}

+ 17 - 0
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)
+	}
+}