mirror of https://github.com/tc39/test262.git
Add tests for additional uses of @@toPrimitive (#666)
This commit is contained in:
parent
ee7496f713
commit
a2b3370b0b
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-date-value
|
||||||
|
es6id: 20.3.2.2
|
||||||
|
description: >
|
||||||
|
Behavior when error thrown while accessing `Symbol.toPrimitive` property
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
3. If NewTarget is not undefined, then
|
||||||
|
a. If Type(value) is Object and value has a [[DateValue]] internal slot,
|
||||||
|
then
|
||||||
|
[...]
|
||||||
|
b. Else,
|
||||||
|
i. Let v be ? ToPrimitive(value).
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var y = Object.defineProperty({}, Symbol.toPrimitive, {
|
||||||
|
get: function() {
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
new Date(y);
|
||||||
|
});
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright (c) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-date-value
|
||||||
|
es6id: 20.3.2.2
|
||||||
|
description: >
|
||||||
|
Behavior when error thrown by invocation of `Symbol.toPrimitive` method
|
||||||
|
during coercion
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
3. If NewTarget is not undefined, then
|
||||||
|
a. If Type(value) is Object and value has a [[DateValue]] internal slot,
|
||||||
|
then
|
||||||
|
[...]
|
||||||
|
b. Else,
|
||||||
|
i. Let v be ? ToPrimitive(value).
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
b. ReturnIfAbrupt(result).
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var y = {};
|
||||||
|
y[Symbol.toPrimitive] = function() {
|
||||||
|
throw new Test262Error();
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
new Date(y);
|
||||||
|
});
|
|
@ -0,0 +1,48 @@
|
||||||
|
// copyright (c) 2016 the v8 project authors. all rights reserved.
|
||||||
|
// this code is governed by the bsd license found in the license file.
|
||||||
|
/*---
|
||||||
|
esid: sec-date-value
|
||||||
|
es6id: 20.3.2.2
|
||||||
|
description: Invocation of `Symbol.toPrimitive` method
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
3. If NewTarget is not undefined, then
|
||||||
|
a. If Type(value) is Object and value has a [[DateValue]] internal slot,
|
||||||
|
then
|
||||||
|
[...]
|
||||||
|
b. Else,
|
||||||
|
i. Let v be ? ToPrimitive(value).
|
||||||
|
[...]
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
1. If PreferredType was not passed, let hint be "default".
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
[...]
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var y = {};
|
||||||
|
var callCount = 0;
|
||||||
|
var thisVal, args;
|
||||||
|
|
||||||
|
y[Symbol.toPrimitive] = function() {
|
||||||
|
callCount += 1;
|
||||||
|
thisVal = this;
|
||||||
|
args = arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
new Date(y);
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 1, 'method invoked exactly once');
|
||||||
|
assert.sameValue(thisVal, y, '`this` value is the object being compared');
|
||||||
|
assert.sameValue(args.length, 1, 'method invoked with exactly one argument');
|
||||||
|
assert.sameValue(
|
||||||
|
args[0],
|
||||||
|
'default',
|
||||||
|
'method invoked with the string "default" as the first argument'
|
||||||
|
);
|
|
@ -0,0 +1,45 @@
|
||||||
|
// copyright (c) 2016 the v8 project authors. all rights reserved.
|
||||||
|
// this code is governed by the bsd license found in the license file.
|
||||||
|
/*---
|
||||||
|
esid: sec-date-value
|
||||||
|
es6id: 20.3.2.2
|
||||||
|
description: >
|
||||||
|
Behavior when coercion via `Symbol.toPrimitive` yields an Object
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
3. If NewTarget is not undefined, then
|
||||||
|
a. If Type(value) is Object and value has a [[DateValue]] internal slot,
|
||||||
|
then
|
||||||
|
[...]
|
||||||
|
b. Else,
|
||||||
|
i. Let v be ? ToPrimitive(value).
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
b. ReturnIfAbrupt(result).
|
||||||
|
c. If Type(result) is not Object, return result.
|
||||||
|
d. Throw a TypeError exception.
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var y = {};
|
||||||
|
var retVal;
|
||||||
|
|
||||||
|
y[Symbol.toPrimitive] = function() {
|
||||||
|
return retVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
retVal = {};
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
new Date(y);
|
||||||
|
}, 'ordinary object');
|
||||||
|
|
||||||
|
retVal = (function() { return arguments; }());
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
new Date(y);
|
||||||
|
}, 'arguments exotic object');
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (c) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-date-value
|
||||||
|
es6id: 20.3.2.2
|
||||||
|
description: >
|
||||||
|
Behavior when coercion via `Symbol.toPrimitive` yields a primitive value
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
3. If NewTarget is not undefined, then
|
||||||
|
a. If Type(value) is Object and value has a [[DateValue]] internal slot,
|
||||||
|
then
|
||||||
|
[...]
|
||||||
|
b. Else,
|
||||||
|
i. Let v be ? ToPrimitive(value).
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
b. ReturnIfAbrupt(result).
|
||||||
|
c. If Type(result) is not Object, return result.
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var y = {};
|
||||||
|
var retVal;
|
||||||
|
|
||||||
|
y[Symbol.toPrimitive] = function() {
|
||||||
|
return retVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
retVal = 1234;
|
||||||
|
assert.sameValue(new Date(y).valueOf(), 1234);
|
||||||
|
|
||||||
|
retVal = '2016-06-03T19:03:52.872Z';
|
||||||
|
assert.sameValue(new Date(y).valueOf(), 1464980632872);
|
||||||
|
|
||||||
|
retVal = Symbol.toPrimitive;
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
new Date(y);
|
||||||
|
});
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-addition-operator-plus-runtime-semantics-evaluation
|
||||||
|
es6id: 12.7.3.1
|
||||||
|
description: >
|
||||||
|
Behavior when error thrown by invocation of `Symbol.toPrimitive` method
|
||||||
|
during coercion
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
5. Let lprim be ? ToPrimitive(lval).
|
||||||
|
6. Let rprim be ? ToPrimitive(rval).
|
||||||
|
[...]
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
b. ReturnIfAbrupt(result).
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var thrower = {};
|
||||||
|
var counter = {};
|
||||||
|
var log;
|
||||||
|
|
||||||
|
Object.defineProperty(thrower, Symbol.toPrimitive, {
|
||||||
|
get: function() {
|
||||||
|
log += 'accessThrower';
|
||||||
|
return function() { throw new Test262Error(); };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(counter, Symbol.toPrimitive, {
|
||||||
|
get: function() {
|
||||||
|
log += 'accessCounter';
|
||||||
|
return function() { log += 'callCounter'; };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
log = '';
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
thrower + counter;
|
||||||
|
}, 'error thrown by left-hand side');
|
||||||
|
assert.sameValue(log, 'accessThrower');
|
||||||
|
|
||||||
|
log = '';
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
counter + thrower;
|
||||||
|
}, 'error thrown by right-hand side');
|
||||||
|
assert.sameValue(log, 'accessCountercallCounteraccessThrower');
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-addition-operator-plus-runtime-semantics-evaluation
|
||||||
|
es6id: 12.7.3.1
|
||||||
|
description: Invocation of `Symbol.toPrimitive` method during coercion
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
5. Let lprim be ? ToPrimitive(lval).
|
||||||
|
6. Let rprim be ? ToPrimitive(rval).
|
||||||
|
[...]
|
||||||
|
|
||||||
|
ES6 Section 7.2.12 Abstract Equality Comparison
|
||||||
|
|
||||||
|
[...]
|
||||||
|
10. If Type(x) is either String, Number, or Symbol and Type(y) is Object,
|
||||||
|
then return the result of the comparison x == ToPrimitive(y).
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
1. If PreferredType was not passed, let hint be "default".
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
[...]
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var left = {};
|
||||||
|
var right = {};
|
||||||
|
var log = '';
|
||||||
|
var leftThisVal, rightThisVal, leftArgs, rightArgs;
|
||||||
|
|
||||||
|
left[Symbol.toPrimitive] = function() {
|
||||||
|
log += 'left';
|
||||||
|
leftThisVal = this;
|
||||||
|
leftArgs = arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
right[Symbol.toPrimitive] = function() {
|
||||||
|
log += 'right';
|
||||||
|
rightThisVal = this;
|
||||||
|
rightArgs = arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
left + right;
|
||||||
|
|
||||||
|
assert.sameValue(log, 'leftright', 'methods invoked in correct sequence');
|
||||||
|
|
||||||
|
assert.sameValue(leftThisVal, left, 'left-hand side `this` value');
|
||||||
|
assert.sameValue(leftArgs.length, 1, 'left-hand side argument length');
|
||||||
|
assert.sameValue(leftArgs[0], 'default', 'left-hand side argument value');
|
||||||
|
|
||||||
|
assert.sameValue(rightThisVal, right, 'right-hand side `this` value');
|
||||||
|
assert.sameValue(rightArgs.length, 1, 'right-hand side argument length');
|
||||||
|
assert.sameValue(rightArgs[0], 'default', 'right-hand side argument value');
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-addition-operator-plus-runtime-semantics-evaluation
|
||||||
|
es6id: 12.7.3.1
|
||||||
|
description: >
|
||||||
|
Behavior when coercion via `Symbol.toPrimitive` yields an Object
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
5. Let lprim be ? ToPrimitive(lval).
|
||||||
|
6. Let rprim be ? ToPrimitive(rval).
|
||||||
|
[...]
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
b. ReturnIfAbrupt(result).
|
||||||
|
c. If Type(result) is not Object, return result.
|
||||||
|
d. Throw a TypeError exception.
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var y = {};
|
||||||
|
var retVal;
|
||||||
|
|
||||||
|
y[Symbol.toPrimitive] = function() {
|
||||||
|
return retVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
retVal = {};
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
0 + y;
|
||||||
|
}, 'ordinary object value, right-hand side');
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
y + 0;
|
||||||
|
}, 'ordinary object value, left-hand side');
|
||||||
|
|
||||||
|
retVal = (function() { return arguments; }());
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
0 + y;
|
||||||
|
}, 'arguments exotic object value, right-hand side');
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
y + 0;
|
||||||
|
}, 'arguments exotic object value, left-hand side');
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-addition-operator-plus-runtime-semantics-evaluation
|
||||||
|
es6id: 12.7.3.1
|
||||||
|
description: >
|
||||||
|
Behavior when coercion via `Symbol.toPrimitive` yields a primitive value
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
5. Let lprim be ? ToPrimitive(lval).
|
||||||
|
6. Let rprim be ? ToPrimitive(rval).
|
||||||
|
7. If Type(lprim) is String or Type(rprim) is String, then
|
||||||
|
a. Let lstr be ? ToString(lprim).
|
||||||
|
b. Let rstr be ? ToString(rprim).
|
||||||
|
c. Return the String that is the result of concatenating lstr and rstr.
|
||||||
|
8. Let lnum be ? ToNumber(lprim).
|
||||||
|
9. Let rnum be ? ToNumber(rprim).
|
||||||
|
10. Return the result of applying the addition operation to lnum and rnum.
|
||||||
|
See the Note below 12.8.5.
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
b. ReturnIfAbrupt(result).
|
||||||
|
c. If Type(result) is not Object, return result.
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var y = {};
|
||||||
|
var retVal;
|
||||||
|
|
||||||
|
y[Symbol.toPrimitive] = function() {
|
||||||
|
return retVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
retVal = 86;
|
||||||
|
assert.sameValue(1 + y, 87);
|
||||||
|
assert.sameValue(y + 2, 88);
|
||||||
|
assert.sameValue('s' + y, 's86');
|
||||||
|
assert.sameValue(y + 's', '86s');
|
||||||
|
|
||||||
|
retVal = 'str';
|
||||||
|
assert.sameValue(0 + y, '0str');
|
||||||
|
assert.sameValue(y + 0, 'str0');
|
||||||
|
assert.sameValue('s' + y, 'sstr');
|
||||||
|
assert.sameValue(y + 's', 'strs');
|
||||||
|
|
||||||
|
retVal = Symbol.toPrimitive;
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
0 + y;
|
||||||
|
}, 'ToNumber(Symbol): right-hand side');
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
y + 0;
|
||||||
|
}, 'ToNumber(Symbol): left-hand side');
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
'' + y;
|
||||||
|
}, 'ToString(Symbol): right-hand side');
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
y + '';
|
||||||
|
}, 'ToString(Symbol): left-hand size');
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-addition-operator-plus-runtime-semantics-evaluation
|
||||||
|
es6id: 12.7.3.1
|
||||||
|
description: >
|
||||||
|
Behavior when error is thrown while accessing `Symbol.toPrimitive` property
|
||||||
|
info: >
|
||||||
|
[...]
|
||||||
|
5. Let lprim be ? ToPrimitive(lval).
|
||||||
|
6. Let rprim be ? ToPrimitive(rval).
|
||||||
|
[...]
|
||||||
|
|
||||||
|
ES6 Section 7.1.1 ToPrimitive ( input [, PreferredType] )
|
||||||
|
|
||||||
|
1. If PreferredType was not passed, let hint be "default".
|
||||||
|
[...]
|
||||||
|
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
|
||||||
|
5. ReturnIfAbrupt(exoticToPrim).
|
||||||
|
6. If exoticToPrim is not undefined, then
|
||||||
|
a. Let result be Call(exoticToPrim, input, «hint»).
|
||||||
|
[...]
|
||||||
|
features: [Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var thrower = {};
|
||||||
|
var counter = {};
|
||||||
|
var callCount = 0;
|
||||||
|
|
||||||
|
Object.defineProperty(thrower, Symbol.toPrimitive, {
|
||||||
|
get: function() {
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(counter, Symbol.toPrimitive, {
|
||||||
|
get: function() {
|
||||||
|
callCount += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
thrower + counter;
|
||||||
|
}, 'error from property access of left-hand side');
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 0);
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
counter + thrower;
|
||||||
|
}, 'error from property access of right-hand side');
|
||||||
|
|
||||||
|
assert.sameValue(callCount, 1);
|
Loading…
Reference in New Issue