From 92423d3c9f2066a45e1569a12fb3589e9ffe3524 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Bargull?= <andre.bargull@gmail.com>
Date: Tue, 22 Dec 2015 19:05:53 +0100
Subject: [PATCH] Add tests for instanceof operator when prototype property is
 primitive or getter

---
 .../primitive-prototype-with-object.js        | 32 +++++++++++++
 .../primitive-prototype-with-primitive.js     | 29 ++++++++++++
 .../prototype-getter-with-object-throws.js    | 42 +++++++++++++++++
 .../prototype-getter-with-object.js           | 47 +++++++++++++++++++
 .../prototype-getter-with-primitive.js        | 34 ++++++++++++++
 5 files changed, 184 insertions(+)
 create mode 100755 test/language/expressions/instanceof/primitive-prototype-with-object.js
 create mode 100755 test/language/expressions/instanceof/primitive-prototype-with-primitive.js
 create mode 100755 test/language/expressions/instanceof/prototype-getter-with-object-throws.js
 create mode 100755 test/language/expressions/instanceof/prototype-getter-with-object.js
 create mode 100755 test/language/expressions/instanceof/prototype-getter-with-primitive.js

diff --git a/test/language/expressions/instanceof/primitive-prototype-with-object.js b/test/language/expressions/instanceof/primitive-prototype-with-object.js
new file mode 100755
index 0000000000..376d379cfc
--- /dev/null
+++ b/test/language/expressions/instanceof/primitive-prototype-with-object.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 12.9.3
+description: >
+  Throws a TypeError if `prototype` property is not an Object.
+info: >
+  12.9.3 Runtime Semantics: Evaluation
+  RelationalExpression : RelationalExpression instanceof ShiftExpression
+    ...
+    7. Return InstanceofOperator(lval, rval).
+
+    12.9.4 Runtime Semantics: InstanceofOperator(O, C)
+    ...
+    6. Return OrdinaryHasInstance(C, O).
+
+    7.3.19 OrdinaryHasInstance
+    ...
+    3. If Type(O) is not Object, return false.
+    4. Let P be Get(C, "prototype").
+    5. ReturnIfAbrupt(P).
+    6. If Type(P) is not Object, throw a TypeError exception.
+    ...
+---*/
+
+// Check with primitive "prototype" property on non-constructor function.
+Function.prototype.prototype = "";
+
+assert.throws(TypeError, function() {
+  [] instanceof Function.prototype;
+});
diff --git a/test/language/expressions/instanceof/primitive-prototype-with-primitive.js b/test/language/expressions/instanceof/primitive-prototype-with-primitive.js
new file mode 100755
index 0000000000..e1682e067e
--- /dev/null
+++ b/test/language/expressions/instanceof/primitive-prototype-with-primitive.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 12.9.3
+description: >
+  Does not throw a TypeError if left-hand side expression and `prototype` property are both primitive values.
+info: >
+  12.9.3 Runtime Semantics: Evaluation
+  RelationalExpression : RelationalExpression instanceof ShiftExpression
+    ...
+    7. Return InstanceofOperator(lval, rval).
+
+    12.9.4 Runtime Semantics: InstanceofOperator(O, C)
+    ...
+    6. Return OrdinaryHasInstance(C, O).
+
+    7.3.19 OrdinaryHasInstance
+    ...
+    3. If Type(O) is not Object, return false.
+    ...
+---*/
+
+// Check with primitive "prototype" property on non-constructor function.
+Function.prototype.prototype = true;
+
+var result = 0 instanceof Function.prototype;
+
+assert.sameValue(result, false);
diff --git a/test/language/expressions/instanceof/prototype-getter-with-object-throws.js b/test/language/expressions/instanceof/prototype-getter-with-object-throws.js
new file mode 100755
index 0000000000..4786e3415a
--- /dev/null
+++ b/test/language/expressions/instanceof/prototype-getter-with-object-throws.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 12.9.3
+description: >
+  "prototype" property is retrieved when left-hand side expression in `instanceof` is object.
+info: >
+  12.9.3 Runtime Semantics: Evaluation
+  RelationalExpression : RelationalExpression instanceof ShiftExpression
+    ...
+    7. Return InstanceofOperator(lval, rval).
+
+    12.9.4 Runtime Semantics: InstanceofOperator(O, C)
+    ...
+    6. Return OrdinaryHasInstance(C, O).
+
+    7.3.19 OrdinaryHasInstance
+    ...
+    3. If Type(O) is not Object, return false.
+    4. Let P be Get(C, "prototype").
+    5. ReturnIfAbrupt(P).
+    ...
+---*/
+
+var getterCalled = false;
+
+function DummyError() { }
+
+// The "prototype" property for constructor functions is a non-configurable data-property,
+// therefore we need to use a non-constructor function to install the getter.
+Object.defineProperty(Function.prototype, "prototype", {
+  get: function() {
+    assert.sameValue(getterCalled, false, "'prototype' getter called once");
+    getterCalled = true;
+    throw new DummyError();
+  }
+});
+
+assert.throws(DummyError, function() {
+  [] instanceof Function.prototype;
+});
diff --git a/test/language/expressions/instanceof/prototype-getter-with-object.js b/test/language/expressions/instanceof/prototype-getter-with-object.js
new file mode 100755
index 0000000000..f395a6ea01
--- /dev/null
+++ b/test/language/expressions/instanceof/prototype-getter-with-object.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 12.9.3
+description: >
+  "prototype" property is retrieved when left-hand side expression in `instanceof` is object.
+info: >
+  12.9.3 Runtime Semantics: Evaluation
+  RelationalExpression : RelationalExpression instanceof ShiftExpression
+    ...
+    7. Return InstanceofOperator(lval, rval).
+
+    12.9.4 Runtime Semantics: InstanceofOperator(O, C)
+    ...
+    6. Return OrdinaryHasInstance(C, O).
+
+    7.3.19 OrdinaryHasInstance
+    ...
+    3. If Type(O) is not Object, return false.
+    4. Let P be Get(C, "prototype").
+    5. ReturnIfAbrupt(P).
+    6. If Type(P) is not Object, throw a TypeError exception.
+    7. Repeat
+      a. Let O be O.[[GetPrototypeOf]]().
+      b. ReturnIfAbrupt(O).
+      c. If O is null, return false.
+      d. If SameValue(P, O) is true, return true.
+    ...
+---*/
+
+var getterCalled = false;
+
+// The "prototype" property for constructor functions is a non-configurable data-property,
+// therefore we need to use a non-constructor function to install the getter.
+Object.defineProperty(Function.prototype, "prototype", {
+  get: function() {
+    assert.sameValue(getterCalled, false, "'prototype' getter called once");
+    getterCalled = true;
+    return Array.prototype;
+  }
+});
+
+var result = [] instanceof Function.prototype;
+
+assert(result, "[] should be instance of Function.prototype");
+assert(getterCalled, "'prototype' getter called");
diff --git a/test/language/expressions/instanceof/prototype-getter-with-primitive.js b/test/language/expressions/instanceof/prototype-getter-with-primitive.js
new file mode 100755
index 0000000000..a59790dca0
--- /dev/null
+++ b/test/language/expressions/instanceof/prototype-getter-with-primitive.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 12.9.3
+description: >
+  "prototype" property is not retrieved when left-hand side expression in `instanceof` is primitive.
+info: >
+  12.9.3 Runtime Semantics: Evaluation
+  RelationalExpression : RelationalExpression instanceof ShiftExpression
+    ...
+    7. Return InstanceofOperator(lval, rval).
+
+    12.9.4 Runtime Semantics: InstanceofOperator(O, C)
+    ...
+    6. Return OrdinaryHasInstance(C, O).
+
+    7.3.19 OrdinaryHasInstance
+    ...
+    3. If Type(O) is not Object, return false.
+    ...
+---*/
+
+// The "prototype" property for constructor functions is a non-configurable data-property,
+// therefore we need to use a non-constructor function to install the getter.
+Object.defineProperty(Function.prototype, "prototype", {
+  get: function() {
+    $ERROR("getter for 'prototype' called");
+  }
+});
+
+var result = 0 instanceof Function.prototype;
+
+assert.sameValue(result, false);
-- 
GitLab