Add tests for additional uses of @@toPrimitive (#666)

This commit is contained in:
jugglinmike 2016-06-10 15:08:59 -04:00 committed by Leo Balter
parent ee7496f713
commit a2b3370b0b
10 changed files with 484 additions and 0 deletions

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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'
);

View File

@ -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');

View File

@ -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);
});

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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);