зеркало из https://github.com/mozilla/rhino.git
Make __proto__ more closely match the spec
Create test cases for the "ES6" behavior that matches the spec, and different tests for the backwardly-compatible behavior.
This commit is contained in:
Родитель
5a8fed1f5d
Коммит
6cc180bd05
|
@ -98,8 +98,13 @@ class SpecialRef extends Ref
|
|||
} while (search != null);
|
||||
}
|
||||
if (type == SPECIAL_PROTO) {
|
||||
if (cx.getLanguageVersion() < Context.VERSION_ES6 ||
|
||||
!(target instanceof BaseFunction)) {
|
||||
if (cx.getLanguageVersion() >= Context.VERSION_ES6) {
|
||||
if ((value != null && !"object".equals(ScriptRuntime.typeof(value))) ||
|
||||
!"object".equals(ScriptRuntime.typeof(target))) {
|
||||
return Undefined.instance;
|
||||
}
|
||||
target.setPrototype(obj);
|
||||
} else {
|
||||
target.setPrototype(obj);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
load('testsrc/assert.js');
|
||||
|
||||
// Test old behavior of "__proto__"
|
||||
|
||||
// __proto__ can be set to lots of things
|
||||
let obj = {};
|
||||
assertTrue(obj.__proto__ === Object.prototype);
|
||||
obj.__proto__ = undefined;
|
||||
assertFalse(obj.__proto__ === Object.prototype);
|
||||
obj.__proto__ = true;
|
||||
assertFalse(obj.__proto__ === Object.prototype);
|
||||
obj.__proto__ = 12345;
|
||||
assertFalse(obj.__proto__ === Object.prototype);
|
||||
obj.__proto__ = 'foobar';
|
||||
assertFalse(obj.__proto__ === Object.prototype);
|
||||
|
||||
// __proto__ on an object can indeed be set to another object
|
||||
let prot = {
|
||||
bar: function() { print('bar'); }
|
||||
};
|
||||
obj = {};
|
||||
assertEquals(prot, obj.__proto__ = prot);
|
||||
assertFalse(obj.__proto__ === Object.prototype);
|
||||
assertEquals('function', typeof obj.__proto__.bar);
|
||||
assertEquals(prot, obj.__proto__);
|
||||
|
||||
// __proto__ on an object can be set to null
|
||||
obj = {};
|
||||
assertNull(obj.__proto__ = null);
|
||||
assertFalse(obj.__proto__ === Object.prototype);
|
||||
|
||||
//__proto__ setting on a non-object also works
|
||||
function f() {}
|
||||
assertTrue(f.__proto__ === Function.prototype);
|
||||
f.__proto__ = prot;
|
||||
assertFalse(f.__proto__ === Function.prototype);
|
||||
assertTrue(f.__proto__ === prot);
|
||||
f.__proto__ = null;
|
||||
assertFalse(f.__proto__ === Function.prototype);
|
||||
|
||||
"success";
|
|
@ -0,0 +1,41 @@
|
|||
load('testsrc/assert.js');
|
||||
|
||||
// Test section B.2.2.1.2 of ECMAScript 6.0, which
|
||||
// defines the behavior of the "__proto__" special property.
|
||||
|
||||
// __proto__ can only be set to an object or to null
|
||||
let obj = {};
|
||||
assertTrue(obj.__proto__ === Object.prototype);
|
||||
assertEquals(undefined, obj.__proto__ = undefined);
|
||||
assertTrue(obj.__proto__ === Object.prototype);
|
||||
assertEquals(undefined, obj.__proto__ = true);
|
||||
assertTrue(obj.__proto__ === Object.prototype);
|
||||
assertEquals(undefined, obj.__proto__ = 12345);
|
||||
assertTrue(obj.__proto__ === Object.prototype);
|
||||
assertEquals(undefined, obj.__proto__ = 'foobar');
|
||||
assertTrue(obj.__proto__ === Object.prototype);
|
||||
|
||||
// __proto__ on an object can indeed be set to another object
|
||||
let prot = {
|
||||
bar: function() { print('bar'); }
|
||||
};
|
||||
obj = {};
|
||||
assertEquals(prot, obj.__proto__ = prot);
|
||||
assertFalse(obj.__proto__ === Object.prototype);
|
||||
assertEquals('function', typeof obj.__proto__.bar);
|
||||
assertEquals(prot, obj.__proto__);
|
||||
|
||||
// __proto__ on an object can be set to null
|
||||
obj = {};
|
||||
assertNull(obj.__proto__ = null);
|
||||
assertFalse(obj.__proto__ === Object.prototype);
|
||||
|
||||
// However, __proto__ setting on a non-object does nothing
|
||||
function f() {}
|
||||
assertTrue(f.__proto__ === Function.prototype);
|
||||
assertEquals(undefined, f.__proto__ = prot);
|
||||
assertTrue(f.__proto__ === Function.prototype);
|
||||
assertEquals(undefined, f.__proto__ = null);
|
||||
assertTrue(f.__proto__ === Function.prototype);
|
||||
|
||||
"success";
|
|
@ -0,0 +1,9 @@
|
|||
package org.mozilla.javascript.tests.backwardcompat;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.drivers.LanguageVersion;
|
||||
import org.mozilla.javascript.drivers.RhinoTest;
|
||||
|
||||
@RhinoTest("testsrc/jstests/backwardcompat/backward-proto-property.js")
|
||||
@LanguageVersion(Context.VERSION_1_8)
|
||||
public class BackwardProtoPropertyTest {}
|
|
@ -1,53 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.javascript.tests.es5;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
|
||||
public class NativeFunctionTest {
|
||||
|
||||
private Context cx;
|
||||
private ScriptableObject scope;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
cx = Context.enter();
|
||||
cx.setLanguageVersion(Context.VERSION_ES6);
|
||||
scope = cx.initStandardObjects();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
Context.exit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionPrototypeNotWritable() {
|
||||
Object result = cx.evaluateString(
|
||||
scope, "function e() {}"
|
||||
+ " e.__proto__ = true;"
|
||||
+ " e.__proto__ != true;",
|
||||
"test", 1, null
|
||||
);
|
||||
assertEquals(true, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionPrototypeNotWritableStrict() {
|
||||
Object result = cx.evaluateString(
|
||||
scope, " 'use strict';"
|
||||
+ " function e() {}"
|
||||
+ " e.__proto__ = true;"
|
||||
+ " e.__proto__ != true;",
|
||||
"test", 1, null
|
||||
);
|
||||
assertEquals(true, result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.mozilla.javascript.tests.es6;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.drivers.LanguageVersion;
|
||||
import org.mozilla.javascript.drivers.RhinoTest;
|
||||
|
||||
@RhinoTest("testsrc/jstests/es6/proto-property.js")
|
||||
@LanguageVersion(Context.VERSION_ES6)
|
||||
public class ProtoPropertyTest {}
|
Загрузка…
Ссылка в новой задаче