Browse Source

Ensure SameAs and StrictEquals behave the same for Objects, as per ECMAScript spec

Dmitry Panov 2 years ago
parent
commit
428fc442ff
2 changed files with 17 additions and 5 deletions
  1. 15 0
      object_test.go
  2. 2 5
      value.go

+ 15 - 0
object_test.go

@@ -495,6 +495,21 @@ func ExampleObject_Delete() {
 	// Output: before: true, after: <nil>
 	// Output: before: true, after: <nil>
 }
 }
 
 
+func TestObjectEquality(t *testing.T) {
+	type CustomInt int
+	type S struct {
+		F CustomInt
+	}
+	vm := New()
+	vm.Set("s", S{})
+	// indexOf() and includes() use different equality checks (StrictEquals and SameValueZero respectively),
+	// but for objects they must behave the same. De-referencing s.F creates a new wrapper each time.
+	vm.testScriptWithTestLib(`
+	assert.sameValue([s.F].indexOf(s.F), 0, "indexOf");
+	assert([s.F].includes(s.F));
+	`, _undefined, t)
+}
+
 func BenchmarkPut(b *testing.B) {
 func BenchmarkPut(b *testing.B) {
 	v := &Object{}
 	v := &Object{}
 
 

+ 2 - 5
value.go

@@ -718,10 +718,7 @@ func (o *Object) ToNumber() Value {
 }
 }
 
 
 func (o *Object) SameAs(other Value) bool {
 func (o *Object) SameAs(other Value) bool {
-	if other, ok := other.(*Object); ok {
-		return o == other
-	}
-	return false
+	return o.StrictEquals(other)
 }
 }
 
 
 func (o *Object) Equals(other Value) bool {
 func (o *Object) Equals(other Value) bool {
@@ -741,7 +738,7 @@ func (o *Object) Equals(other Value) bool {
 
 
 func (o *Object) StrictEquals(other Value) bool {
 func (o *Object) StrictEquals(other Value) bool {
 	if other, ok := other.(*Object); ok {
 	if other, ok := other.(*Object); ok {
-		return o == other || o.self.equal(other.self)
+		return o == other || o != nil && other != nil && o.self.equal(other.self)
 	}
 	}
 	return false
 	return false
 }
 }