diff --git a/test/built-ins/GeneratorFunction/has-instance.js b/test/built-ins/GeneratorFunction/has-instance.js new file mode 100644 index 0000000000..0f69a38895 --- /dev/null +++ b/test/built-ins/GeneratorFunction/has-instance.js @@ -0,0 +1,33 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + Generator function instances are correctly reported as instances of the + GeneratorFunction intrinsic. +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +function* gDecl() {} +var gExpr = function* () {}; + +assert( + gDecl instanceof GeneratorFunction, + 'Generators created via GeneratorDeclaration syntax are proper instances of GeneratorFunction' +); + +assert( + gExpr instanceof GeneratorFunction, + 'Generators created via GeneratorExpression syntax are proper instances of GeneratorFunction' +); + +assert( + new GeneratorFunction() instanceof GeneratorFunction, + 'Generators created via constructor invocation of GeneratorFunction are proper instances of GeneratorFunction' +); + +assert( + GeneratorFunction() instanceof GeneratorFunction, + 'Generators created via function invocation of GeneratorFunction are proper instances of GeneratorFunction' +); diff --git a/test/built-ins/GeneratorFunction/invoked-as-constructor-no-arguments.js b/test/built-ins/GeneratorFunction/invoked-as-constructor-no-arguments.js new file mode 100644 index 0000000000..bb70482e3c --- /dev/null +++ b/test/built-ins/GeneratorFunction/invoked-as-constructor-no-arguments.js @@ -0,0 +1,17 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When invoked via the constructor invocation pattern without arguments, the + GeneratorFunction intrinsic returns a valid generator with an empty body. +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +var g = new GeneratorFunction(); +var iter = g(); +var result = iter.next(); + +assert.sameValue(result.value, undefined, 'Result `value`'); +assert.sameValue(result.done, true, 'Result `done` flag'); diff --git a/test/built-ins/GeneratorFunction/invoked-as-function-multiple-arguments.js b/test/built-ins/GeneratorFunction/invoked-as-function-multiple-arguments.js new file mode 100644 index 0000000000..e3c83abdc8 --- /dev/null +++ b/test/built-ins/GeneratorFunction/invoked-as-function-multiple-arguments.js @@ -0,0 +1,24 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When invoked via the function invocation pattern with multiple arguments, + the GeneratorFunction intrinsic creates a valid generator whose body is the + last argument evaluated as source code and whose formal parameters are + defined by the preceeding arguments. +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +var g = GeneratorFunction('x', 'y', 'yield x + y;'); +var iter = g(2, 3); +var result; + +result = iter.next(); +assert.sameValue(result.value, 5, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/built-ins/GeneratorFunction/invoked-as-function-no-arguments.js b/test/built-ins/GeneratorFunction/invoked-as-function-no-arguments.js new file mode 100644 index 0000000000..52d6686da9 --- /dev/null +++ b/test/built-ins/GeneratorFunction/invoked-as-function-no-arguments.js @@ -0,0 +1,17 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When invoked via the function invocation pattern without arguments, the + GeneratorFunction intrinsic returns a valid generator with an empty body. +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +var g = GeneratorFunction(); +var iter = g(); +var result = iter.next(); + +assert.sameValue(result.value, undefined, 'Result `value`'); +assert.sameValue(result.done, true, 'Result `done` flag'); diff --git a/test/built-ins/GeneratorFunction/invoked-as-function-single-argument.js b/test/built-ins/GeneratorFunction/invoked-as-function-single-argument.js new file mode 100644 index 0000000000..8e1411039a --- /dev/null +++ b/test/built-ins/GeneratorFunction/invoked-as-function-single-argument.js @@ -0,0 +1,23 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When invoked via the function invocation pattern with a single argument, + the GeneratorFunction intrinsic creates a valid generator whose body is the + first argument evaluated as source code. +---*/ + +var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; + +var g = GeneratorFunction('yield 1;'); +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/built-ins/GeneratorFunction/property-descriptor.js b/test/built-ins/GeneratorFunction/property-descriptor.js new file mode 100644 index 0000000000..4594a8846a --- /dev/null +++ b/test/built-ins/GeneratorFunction/property-descriptor.js @@ -0,0 +1,20 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + The GeneratorPrototype intrinsic should define a `constructor` property + that is non-enumerable, non-writable, and configurable. +includes: [propertyHelper.js] +es6id: 25.3.1 +---*/ + +function* g() {} +var Generator = Object.getPrototypeOf(g); +var GeneratorPrototype = Generator.prototype; + +assert.sameValue(GeneratorPrototype.constructor, Generator); + +verifyNotEnumerable(GeneratorPrototype, 'constructor'); +verifyNotWritable(GeneratorPrototype, 'constructor'); +verifyConfigurable(GeneratorPrototype, 'constructor'); diff --git a/test/built-ins/GeneratorFunction/prototype/prototype.js b/test/built-ins/GeneratorFunction/prototype/prototype.js new file mode 100644 index 0000000000..742611edfc --- /dev/null +++ b/test/built-ins/GeneratorFunction/prototype/prototype.js @@ -0,0 +1,13 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2.3.2 +description: > + The value of GeneratorFunction.prototype.prototype is the + %GeneratorPrototype% intrinsic object. +---*/ + +assert.sameValue( + Object.getPrototypeOf(function*() {}).prototype, + Object.getPrototypeOf(function*() {}.prototype) +); diff --git a/test/built-ins/GeneratorFunction/prototype/toStringTag.js b/test/built-ins/GeneratorFunction/prototype/toStringTag.js new file mode 100644 index 0000000000..3008a50608 --- /dev/null +++ b/test/built-ins/GeneratorFunction/prototype/toStringTag.js @@ -0,0 +1,19 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + The GeneratorFunctionPrototype defines an `@@toStringTag` property. +es6id: 25.2.3.3 +includes: [propertyHelper.js] +---*/ + +var GeneratorFunctionPrototype = Object.getPrototypeOf(function*() {}); + +assert.sameValue( + GeneratorFunctionPrototype[Symbol.toStringTag], 'GeneratorFunction' +); + +verifyNotEnumerable(GeneratorFunctionPrototype, Symbol.toStringTag); +verifyNotWritable(GeneratorFunctionPrototype, Symbol.toStringTag); +verifyConfigurable(GeneratorFunctionPrototype, Symbol.toStringTag); diff --git a/test/built-ins/GeneratorPrototype/Symbol.toStringTag.js b/test/built-ins/GeneratorPrototype/Symbol.toStringTag.js new file mode 100644 index 0000000000..f684cd9c72 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/Symbol.toStringTag.js @@ -0,0 +1,19 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + The Generator prototype defines a `@@toStringTag` attribute. +es6id: 25.3.1.5 +includes: [propertyHelper.js] +---*/ + +var GeneratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf(function*() {}()) +); + +assert.sameValue(GeneratorPrototype[Symbol.toStringTag], 'Generator'); + +verifyNotEnumerable(GeneratorPrototype, Symbol.toStringTag); +verifyNotWritable(GeneratorPrototype, Symbol.toStringTag); +verifyConfigurable(GeneratorPrototype, Symbol.toStringTag); diff --git a/test/built-ins/GeneratorPrototype/next/consecutive-yields.js b/test/built-ins/GeneratorPrototype/next/consecutive-yields.js new file mode 100644 index 0000000000..0288eae2a3 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/consecutive-yields.js @@ -0,0 +1,24 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When a generator body contains two consecutive yield statements, it should + produce an iterable that visits each yielded value and then completes. +---*/ + +function* g() { yield 1; yield 2; } +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Third result `value`'); +assert.sameValue(result.done, true, 'Third result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/next/context-constructor-invocation.js b/test/built-ins/GeneratorPrototype/next/context-constructor-invocation.js new file mode 100644 index 0000000000..1c5643cdd2 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/context-constructor-invocation.js @@ -0,0 +1,16 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + If the generator was invoked using [[Construct]], the this bind is not + initialized and any references to `this` within the FunctionBody will + produce a ReferenceError exception. +---*/ + +function* g() { this; } +var iter = new g(); + +assert.throws(ReferenceError, function() { + iter.next(); +}); diff --git a/test/built-ins/GeneratorPrototype/next/context-method-invocation.js b/test/built-ins/GeneratorPrototype/next/context-method-invocation.js new file mode 100644 index 0000000000..c80e13b1c8 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/context-method-invocation.js @@ -0,0 +1,17 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When a generator function is invoked as a method of an object, its context + is that object. +---*/ + +var context; +function* g() { context = this; } +var obj = { g: g }; +var iter = obj.g(); + +iter.next(); + +assert.sameValue(context, obj); diff --git a/test/built-ins/GeneratorPrototype/next/from-state-executing.js b/test/built-ins/GeneratorPrototype/next/from-state-executing.js new file mode 100644 index 0000000000..2a49244f3b --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/from-state-executing.js @@ -0,0 +1,25 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.3.2 +description: > + A TypeError should be thrown if the generator is resumed while running. +---*/ + +var iter; +function* withoutVal() { + iter.next(); +} +function* withVal() { + iter.next(42); +} + +iter = withoutVal(); +assert.throws(TypeError, function() { + iter.next(); +}); + +iter = withVal(); +assert.throws(TypeError, function() { + iter.next(); +}); diff --git a/test/built-ins/GeneratorPrototype/next/incorrect-context.js b/test/built-ins/GeneratorPrototype/next/incorrect-context.js new file mode 100644 index 0000000000..e88f109dd5 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/incorrect-context.js @@ -0,0 +1,22 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.2 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the + context of `next` does not defined the [[GeneratorState]] internal slot. +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.throws(TypeError, function() { GeneratorPrototype.next.call(1); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call(1, 1); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call({}); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call({}, 1); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call(function() {}); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call(function() {}, 1); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call(g); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call(g, 1); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call(g.prototype); }); +assert.throws(TypeError, function() { GeneratorPrototype.next.call(g.prototype, 1); }); diff --git a/test/built-ins/GeneratorPrototype/next/lone-return.js b/test/built-ins/GeneratorPrototype/next/lone-return.js new file mode 100644 index 0000000000..7afdb9dae3 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/lone-return.js @@ -0,0 +1,16 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When a generator body contains a lone return statement, it should produce + an iterator that immediately completes with the returned value. +---*/ + +function* g() { return 23; } +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 23, 'Result value'); +assert.sameValue(result.done, true, 'Result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/next/lone-yield.js b/test/built-ins/GeneratorPrototype/next/lone-yield.js new file mode 100644 index 0000000000..90b2eddae3 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/lone-yield.js @@ -0,0 +1,20 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When a generator body contains a lone yield statement, it should produce an + iterable that visits the yielded value and then completes. +---*/ + +function* g() { yield 1; } +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Second result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/next/no-control-flow.js b/test/built-ins/GeneratorPrototype/next/no-control-flow.js new file mode 100644 index 0000000000..9ce9f920a1 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/no-control-flow.js @@ -0,0 +1,21 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When a generator body contains no control flow statements, it should + produce an iterator that is initially completed with `undefined` as its + value. +---*/ + +function* g() {} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, undefined, 'First result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Second result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/next/property-descriptor.js b/test/built-ins/GeneratorPrototype/next/property-descriptor.js new file mode 100644 index 0000000000..58166bffce --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/property-descriptor.js @@ -0,0 +1,17 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + The GeneratorPrototype intrinsic should define a `next` property that is + non-enumerable, writable, and configurable (as per section 17). +includes: [propertyHelper.js] +es6id: 25.3.1 +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +verifyNotEnumerable(GeneratorPrototype, 'next'); +verifyWritable(GeneratorPrototype, 'next'); +verifyConfigurable(GeneratorPrototype, 'next'); diff --git a/test/built-ins/GeneratorPrototype/next/result-prototype.js b/test/built-ins/GeneratorPrototype/next/result-prototype.js new file mode 100644 index 0000000000..441e686948 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/result-prototype.js @@ -0,0 +1,19 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + The `next` method returns an object that has "own" properties `value` and + `done` and that inherits directly from the Object prototype. +---*/ + +function* g() {} +var result = g().next(); + +assert( + Object.hasOwnProperty.call(result, 'value'), 'Has "own" property `value`' +); +assert( + Object.hasOwnProperty.call(result, 'done'), 'Has "own" property `done`' +); +assert.sameValue(Object.getPrototypeOf(result), Object.prototype); diff --git a/test/built-ins/GeneratorPrototype/next/return-yield-expr.js b/test/built-ins/GeneratorPrototype/next/return-yield-expr.js new file mode 100644 index 0000000000..62a54d8b7e --- /dev/null +++ b/test/built-ins/GeneratorPrototype/next/return-yield-expr.js @@ -0,0 +1,21 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + Yield expressions are valid yield expression operands. +---*/ + +function* g() { + return yield 1; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(3); +assert.sameValue(result.value, 3, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/throw/from-state-completed.js b/test/built-ins/GeneratorPrototype/throw/from-state-completed.js new file mode 100644 index 0000000000..ce07d134c3 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/from-state-completed.js @@ -0,0 +1,22 @@ +// Copyright (C) 2014 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + Resuming abuptly from a generator in the 'completed' state should honor the + abrupt completion and remain in the 'completed' state. +---*/ + +function E() {} +function* G() {} +var iter; + +iter = G(); +iter.next(); + +assert.throws(E, function() { iter.throw(new E()); }); + +result = iter.next(); + +assert.sameValue(result.value, undefined, 'Result `value`'); +assert.sameValue(result.done, true, 'Result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/throw/from-state-executing.js b/test/built-ins/GeneratorPrototype/throw/from-state-executing.js new file mode 100644 index 0000000000..546ef91040 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/from-state-executing.js @@ -0,0 +1,18 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.3.2 +description: > + A TypeError should be thrown if the generator is resumed abruptly while + running. +---*/ + +var iter; +function* g() { + iter.throw(42); +} + +iter = g(); +assert.throws(TypeError, function() { + iter.next(); +}); diff --git a/test/built-ins/GeneratorPrototype/throw/from-state-suspended-start.js b/test/built-ins/GeneratorPrototype/throw/from-state-suspended-start.js new file mode 100644 index 0000000000..b3234c863c --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/from-state-suspended-start.js @@ -0,0 +1,24 @@ +// Copyright (C) 2014 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + Resuming abuptly from a generator in the 'suspendedStart' state should + honor the abrupt completion and trigger a transition into the 'completed' + state. +---*/ + +function E() {} +function* G() { + yield 1; + yield 2; +} +var iter; + +iter = G(); +assert.throws(E, function() { iter.throw(new E()); }); + +result = iter.next(); + +assert.sameValue(result.value, undefined, 'Result `value`'); +assert.sameValue(result.done, true, 'Result `done` flag'); diff --git a/test/built-ins/GeneratorPrototype/throw/incorrect-context.js b/test/built-ins/GeneratorPrototype/throw/incorrect-context.js new file mode 100644 index 0000000000..827292acbb --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/incorrect-context.js @@ -0,0 +1,17 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + A TypeError should be thrown from GeneratorValidate (25.3.3.2) if the + context of `throw` does not defined the [[GeneratorState]] internal slot. +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +assert.throws(TypeError, function() { GeneratorPrototype.throw.call(1); }); +assert.throws(TypeError, function() { GeneratorPrototype.throw.call({}); }); +assert.throws(TypeError, function() { GeneratorPrototype.throw.call(function() {}); }); +assert.throws(TypeError, function() { GeneratorPrototype.throw.call(g); }); +assert.throws(TypeError, function() { GeneratorPrototype.throw.call(g.prototype); }); diff --git a/test/built-ins/GeneratorPrototype/throw/property-descriptor.js b/test/built-ins/GeneratorPrototype/throw/property-descriptor.js new file mode 100644 index 0000000000..b9589e1194 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/property-descriptor.js @@ -0,0 +1,17 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + The GeneratorPrototype intrinsic should define a `throw` property that is + non-enumerable, writable, and configurable (as per section 17). +includes: [propertyHelper.js] +es6id: 25.3.1 +---*/ + +function* g() {} +var GeneratorPrototype = Object.getPrototypeOf(g).prototype; + +verifyNotEnumerable(GeneratorPrototype, 'throw'); +verifyWritable(GeneratorPrototype, 'throw'); +verifyConfigurable(GeneratorPrototype, 'throw'); diff --git a/test/built-ins/GeneratorPrototype/throw/try-catch-before-try.js b/test/built-ins/GeneratorPrototype/throw/try-catch-before-try.js new file mode 100644 index 0000000000..3b5f7d13a9 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-before-try.js @@ -0,0 +1,35 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused before a `try..catch` statement, `throw` should + interrupt control flow as if a `throw` statement had appeared at that + location in the function body. +---*/ + +function* g() { + yield 1; + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; +} +var iter, result, exception; + +iter = g(); + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); +assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); + +result = iter.next(); +assert.sameValue(result.value, + undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js b/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js new file mode 100644 index 0000000000..d000b99b8c --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-following-catch.js @@ -0,0 +1,43 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is puased after a `try..catch` statement, `throw` should + interrupt control flow as if a `throw` statement had appeared at that + location in the function body. +---*/ + +function* g() { + yield 1; + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; +} +var iter, result, exception; + +exception = new Test262Error(); +iter = g(); +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.throw(exception); +assert.sameValue(result.value, exception, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); +assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js b/test/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js new file mode 100644 index 0000000000..9e2329e9d4 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-within-catch.js @@ -0,0 +1,49 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within the `catch` block of a `try..catch` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +---*/ + +function* g() { + yield 1; + try { + yield 2; + throw exception; + } catch (e) { + yield e; + } + yield 3; +} +var iter, result, exception; + +exception = new Test262Error(); +iter = g(); + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, exception, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 3, 'Fourth result `value`'); +assert.sameValue(result.done, false, 'Fourth result `done` flag'); +assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-catch-within-try.js b/test/built-ins/GeneratorPrototype/throw/try-catch-within-try.js new file mode 100644 index 0000000000..b768c3860c --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-catch-within-try.js @@ -0,0 +1,47 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within the `try` block of a `try..catch` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +---*/ + +function* g() { + yield 1; + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; +} +var iter, result, exception; + +exception = new Test262Error(); +iter = g(); + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.throw(exception); +assert.sameValue(result.value, exception, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 3, 'Fourth result `done` flag'); +assert.sameValue(result.done, false, 'Fourth result `value`'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-before-try.js b/test/built-ins/GeneratorPrototype/throw/try-finally-before-try.js new file mode 100644 index 0000000000..87518726ba --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-before-try.js @@ -0,0 +1,38 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused before a `try..finally` statement, `throw` + should interrupt control flow as if a `throw` statement had appeared at + that location in the function body. +---*/ + +function* g() { + yield 1; + try { + yield 2; + } finally { + yield 3; + } + yield 4; +} +var iter, result; + +iter = g(); + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue( + result.done, false, 'First result `done` flag' +); + +assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue( result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js b/test/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js new file mode 100644 index 0000000000..7db1bbca3a --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-following-finally.js @@ -0,0 +1,43 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused after a `try..finally` statement, `throw` should + interrupt control flow as if a `throw` statement had appeared at that + location in the function body. +---*/ + +function* g() { + yield 1; + try { + yield 2; + } finally { + yield 3; + } + yield 4; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.throw(new Error()); +assert.sameValue(result.value, 3, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js new file mode 100644 index 0000000000..abc3466dd3 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-catch.js @@ -0,0 +1,55 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within a `catch` block that is declared within a + `try` block of a `try..catch` statement, `throw` should interrupt control + flow as if a `throw` statement had appeared at that location in the + function body. +---*/ + +function* g() { + try { + yield 1; + try { + yield 2; + throw exception; + } catch (e) { + yield e; + } + yield 3; + } finally { + yield 4; + } + yield 5; +} +var exception = new Error(); +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, exception, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.throw(new Test262Error()); +assert.sameValue(result.value, 4, 'Fourth result `value`'); +assert.sameValue(result.done, false, 'Fourth result `done` flag'); + +assert.throws(Test262Error, function() { iter.next(); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js new file mode 100644 index 0000000000..8c3ec7377a --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-finally.js @@ -0,0 +1,45 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within a `finally` block of a `try..catch` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +---*/ + +function* g() { + try { + yield 1; + throw new Error(); + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; + } finally { + yield 4; + } + yield 5; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 4, 'Second result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js new file mode 100644 index 0000000000..38a40083d4 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-inner-try.js @@ -0,0 +1,60 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within a `try` block that is declared within a + `try` block of a `try..catch` statement, `throw` should interrupt control + flow as if a `throw` statement had appeared at that location in the + function body. +---*/ + +function* g() { + try { + yield 1; + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; + } finally { + yield 4; + } + yield 5; +} +var iter = g(); +var exception = new Error(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result value'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.throw(exception); +assert.sameValue(result.value, exception, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 3, 'Fourth result `value'); +assert.sameValue(result.done, false, 'Fourth result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 4, 'Fifth result `value`'); +assert.sameValue(result.done, false, 'Firth result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 5, 'Sixth result `value`'); +assert.sameValue(result.done, false, 'Sixth result `done` flag'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js new file mode 100644 index 0000000000..f5d8d5f5f8 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-after-nested.js @@ -0,0 +1,59 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within a `try` block of a `try..catch` statement + and following a nested `try..catch` statment, `throw` should interrupt + control flow as if a `throw` statement had appeared at that location in the + function body. +---*/ + +function* g() { + try { + yield 1; + try { + yield 2; + throw exception; + } catch (e) { + yield e; + } + yield 3; + } finally { + yield 4; + } + yield 5; +} +var exception = new Error(); +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, exception, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 3, 'Fourth result `value`'); +assert.sameValue(result.done, false, 'Fourth result `done` flag'); + +result = iter.throw(new Test262Error()); +assert.sameValue(result.value, 4, 'Fifth result `value`'); +assert.sameValue(result.done, false, 'Fifth result `done` flag'); + +assert.throws(Test262Error, function() { iter.next(); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js new file mode 100644 index 0000000000..d01910e08b --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-nested-try-catch-within-outer-try-before-nested.js @@ -0,0 +1,47 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within a `try` block of a `try..catch` statement + and before a nested `try..catch` statement, `throw` should interrupt + control flow as if a `throw` statement had appeared at that location in the + function body. +---*/ + +function* g() { + try { + yield 1; + try { + yield 2; + } catch (e) { + yield e; + } + yield 3; + } finally { + yield 4; + } + yield 5; +} +var iter = g(); +var result; + +iter = g(); + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.throw(new Test262Error()); +assert.sameValue(result.value, 4, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +assert.throws(Test262Error, function() { iter.next(); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js b/test/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js new file mode 100644 index 0000000000..1345eeaee9 --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-within-finally.js @@ -0,0 +1,47 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within the `finally` block of a `try..finally` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +---*/ + +function* g() { + yield 1; + try { + yield 2; + } finally { + yield 3; + } + yield 4; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 3, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 4, 'Fourth result `value`'); +assert.sameValue(result.done, false, 'Fourth result `done` flag'); + +assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/built-ins/GeneratorPrototype/throw/try-finally-within-try.js b/test/built-ins/GeneratorPrototype/throw/try-finally-within-try.js new file mode 100644 index 0000000000..d7c28f8b3b --- /dev/null +++ b/test/built-ins/GeneratorPrototype/throw/try-finally-within-try.js @@ -0,0 +1,43 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.3.1.4 +description: > + When a generator is paused within a `try` block of a `try..finally` + statement, `throw` should interrupt control flow as if a `throw` statement + had appeared at that location in the function body. +---*/ + +function* g() { + yield 1; + try { + yield 2; + } finally { + yield 3; + } + yield 4; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 3, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +assert.throws(Test262Error, function() { iter.throw(new Test262Error()); }); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Result `value` is undefined when done' +); +assert.sameValue(result.done, true, 'Result `done` flag is `true` when done'); + +iter.next(); diff --git a/test/language/expressions/generators/prototype-own-properties.js b/test/language/expressions/generators/prototype-own-properties.js new file mode 100644 index 0000000000..e46c3c38eb --- /dev/null +++ b/test/language/expressions/generators/prototype-own-properties.js @@ -0,0 +1,11 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2.4.2 +description: > + The `prototype` property of GeneratorFunction instances are created as + plain objects with no "own" properties. +---*/ + +var ownProperties = Object.getOwnPropertyNames(function*() {}.prototype); +assert.sameValue(ownProperties.length, 0); diff --git a/test/language/expressions/generators/prototype-uniqueness.js b/test/language/expressions/generators/prototype-uniqueness.js new file mode 100644 index 0000000000..015362f943 --- /dev/null +++ b/test/language/expressions/generators/prototype-uniqueness.js @@ -0,0 +1,13 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + GeneratorFunction instances are created with a unique prototype object. +es6id: 25.2.1 +---*/ + +var g1 = function*() {}; +var g2 = function*() {}; + +assert(g1.prototype !== g2.prototype); diff --git a/test/language/expressions/yield/arguments-object-attributes.js b/test/language/expressions/yield/arguments-object-attributes.js new file mode 100644 index 0000000000..0b07fe237e --- /dev/null +++ b/test/language/expressions/yield/arguments-object-attributes.js @@ -0,0 +1,40 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + Attributes of the `arguments` object are valid yield expression operands. +---*/ + +function* g() { + yield arguments[0]; + yield arguments[1]; + yield arguments[2]; + yield arguments[3]; +} +var iter = g(23, 45, 33); +var result; + +result = iter.next(); +assert.sameValue(result.value, 23, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 45, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 33, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Fourth result `value` (unspecified parameter)' +); +assert.sameValue( + result.done, false, 'Fourth result `done` flag (unspecified parameter)' +); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/captured-free-vars.js b/test/language/expressions/yield/captured-free-vars.js new file mode 100644 index 0000000000..7452642c66 --- /dev/null +++ b/test/language/expressions/yield/captured-free-vars.js @@ -0,0 +1,35 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + Free variables captured within the GeneratorFunction closure are valid + yield expression operands. +---*/ + +var a = 1; +var b = 2; +var c = 3; +function* g() { + yield a; + yield b; + yield c; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 3, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/expr-value-specified.js b/test/language/expressions/yield/expr-value-specified.js new file mode 100644 index 0000000000..36bc0cf89d --- /dev/null +++ b/test/language/expressions/yield/expr-value-specified.js @@ -0,0 +1,28 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When the `next` method of a generator-produced iterable is invoked without + an argument, the corresponding `yield` expression should be evaluated as + `undefined`. +---*/ + +function* g() { actual = yield; } +var expected = {}; +var iter = g(); +var actual, result; + +result = iter.next(); +assert.sameValue(result.value, undefined, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); +assert.sameValue( + actual, undefined, 'Value of `yield` expression (prior to continuation)' +); + +result = iter.next(expected); +assert.sameValue(result.value, undefined, 'Second result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); +assert.sameValue( + actual, expected, 'Value of `yield` expression (following continuation)' +); diff --git a/test/language/expressions/yield/expr-value-unspecified.js b/test/language/expressions/yield/expr-value-unspecified.js new file mode 100644 index 0000000000..782f09f394 --- /dev/null +++ b/test/language/expressions/yield/expr-value-unspecified.js @@ -0,0 +1,23 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When the `next` method of a generator-produced iterable is invoked without + an argument, the corresponding `yield` expression should be evaluated as + `undefined`. +---*/ + +function* g() { actual = yield; } +var iter = g(); +var actual, result; + +result = iter.next(); +assert.sameValue(result.value, undefined); +assert.sameValue(result.done, false); +assert.sameValue(actual, undefined); + +result = iter.next(); +assert.sameValue(result.value, undefined); +assert.sameValue(result.done, true); +assert.sameValue(actual, undefined); diff --git a/test/language/expressions/yield/formal-parameters-after-reassignment-non-strict.js b/test/language/expressions/yield/formal-parameters-after-reassignment-non-strict.js new file mode 100644 index 0000000000..4982ad0ea1 --- /dev/null +++ b/test/language/expressions/yield/formal-parameters-after-reassignment-non-strict.js @@ -0,0 +1,44 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + Formal parameters are valid yield expression operands. +flags: [noStrict] +---*/ + +function* g(a, b, c, d) { + arguments[0] = 32; + arguments[1] = 54; + arguments[2] = 333; + yield a; + yield b; + yield c; + yield d; +} +var iter = g(23, 45, 33); +var result; + +result = iter.next(); +assert.sameValue(result.value, 32, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 54, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 333, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Fourth result `value` (unspecified parameter)' +); +assert.sameValue( + result.done, false, 'Fourth result `done` flag (unspecified parameter)' +); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/formal-parameters-after-reassignment-strict.js b/test/language/expressions/yield/formal-parameters-after-reassignment-strict.js new file mode 100644 index 0000000000..9af7d44595 --- /dev/null +++ b/test/language/expressions/yield/formal-parameters-after-reassignment-strict.js @@ -0,0 +1,44 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + Formal parameters are valid yield expression operands. +flags: [onlyStrict] +---*/ + +function* g(a, b, c, d) { + arguments[0] = 32; + arguments[1] = 54; + arguments[2] = 333; + yield a; + yield b; + yield c; + yield d; +} +var iter = g(23, 45, 33); +var result; + +result = iter.next(); +assert.sameValue(result.value, 23, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 45, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 33, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Fourth result `value` (unspecified parameter)' +); +assert.sameValue( + result.done, false, 'Fourth result `done` flag (unspecified parameter)' +); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/formal-parameters.js b/test/language/expressions/yield/formal-parameters.js new file mode 100644 index 0000000000..31c7f1515e --- /dev/null +++ b/test/language/expressions/yield/formal-parameters.js @@ -0,0 +1,40 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + Formal parameters are valid yield expression operands. +---*/ + +function* g(a, b, c, d) { + yield a; + yield b; + yield c; + yield d; +} +var iter = g(23, 45, 33); +var result; + +result = iter.next(); +assert.sameValue(result.value, 23, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 45, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 33, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue( + result.value, undefined, 'Fourth result `value` (unspecified parameter)' +); +assert.sameValue( + result.done, false, 'Fourth result `done` flag (unspecified parameter)' +); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/from-catch.js b/test/language/expressions/yield/from-catch.js new file mode 100644 index 0000000000..4cc788d3a3 --- /dev/null +++ b/test/language/expressions/yield/from-catch.js @@ -0,0 +1,26 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + The behavior of `yield` expressions should not be affected when they appear + within the `catch` block of `try` statements. +---*/ + +function* g() { + try { + throw new Error(); + } catch (err) { + yield 1; + } +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done`flag'); diff --git a/test/language/expressions/yield/from-try.js b/test/language/expressions/yield/from-try.js new file mode 100644 index 0000000000..e058c6d4ce --- /dev/null +++ b/test/language/expressions/yield/from-try.js @@ -0,0 +1,26 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + The behavior of `yield` expressions should not be affected when they appear + within the `try` block of `try` statements. +---*/ + +function* g() { + try { + yield 1; + } catch (err) { + throw err; + } +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done`flag'); diff --git a/test/language/expressions/yield/from-with.js b/test/language/expressions/yield/from-with.js new file mode 100644 index 0000000000..e3f53312a8 --- /dev/null +++ b/test/language/expressions/yield/from-with.js @@ -0,0 +1,38 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + The operand to a `yield` expression should honor the semantics of the + `with` statement. +---*/ + +function* g() { + var x = 1; + + yield x; + + with ({ x: 2 }) { + yield x; + } + + yield x; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 1, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/star-array.js b/test/language/expressions/yield/star-array.js new file mode 100644 index 0000000000..b82a29e935 --- /dev/null +++ b/test/language/expressions/yield/star-array.js @@ -0,0 +1,30 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When an array is the operand of a `yield *` expression, the generator + should produce an iterator that visits each element in order. +---*/ + +function* g() { + yield* [1, 2, 3]; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 3, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/star-iterable.js b/test/language/expressions/yield/star-iterable.js new file mode 100644 index 0000000000..e961c2ca7e --- /dev/null +++ b/test/language/expressions/yield/star-iterable.js @@ -0,0 +1,39 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When an iterator is the operand of a `yield *` expression, the generator + should produce an iterator that visits each iterated item. +---*/ + +var results = [{ value: 1 }, { value: 8 }, { value: 34, done: true }]; +var idx = 0; +var iterator = {}; +var iterable = { + next: function() { + var result = results[idx]; + idx += 1; + return result; + } +}; +iterator[Symbol.iterator] = function() { + return iterable; +}; +function* g() { + yield* iterator; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, undefined, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 8, 'Third result `value`'); +assert.sameValue(result.done, undefined, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/star-string.js b/test/language/expressions/yield/star-string.js new file mode 100644 index 0000000000..ef636e6307 --- /dev/null +++ b/test/language/expressions/yield/star-string.js @@ -0,0 +1,30 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When a string is the operand of a `yield *` expression, the generator + should produce an iterator that visits each character in order. +---*/ + +function* g() { + yield* 'abc'; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 'a', 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 'b', 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 'c', 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/then-return.js b/test/language/expressions/yield/then-return.js new file mode 100644 index 0000000000..5f4af89d46 --- /dev/null +++ b/test/language/expressions/yield/then-return.js @@ -0,0 +1,21 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + When a generator body contains a yield statement followed by a return + statement, it should produce an iterator that visits the yieled value and + completes on the returned value. +---*/ + +function* g() { yield 1; return 2; } +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Second result `value`'); +assert.sameValue(result.done, true, 'Second result `done` flag'); diff --git a/test/language/expressions/yield/within-for.js b/test/language/expressions/yield/within-for.js new file mode 100644 index 0000000000..95b56786d7 --- /dev/null +++ b/test/language/expressions/yield/within-for.js @@ -0,0 +1,31 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + `yield` expressions should suspend `for` loop iteration. +---*/ + +function* g() { + for (var idx = 0; idx < 3; idx++) { + yield idx; + } +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 0, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 1, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, 2, 'Third result `value`'); +assert.sameValue(result.done, false, 'Third result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done` flag'); diff --git a/test/language/expressions/yield/yield-expr.js b/test/language/expressions/yield/yield-expr.js new file mode 100644 index 0000000000..4758167883 --- /dev/null +++ b/test/language/expressions/yield/yield-expr.js @@ -0,0 +1,25 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2 +description: > + Yield expressions are valid yield expression operands. +---*/ + +function* g() { + yield yield 1; +} +var iter = g(); +var result; + +result = iter.next(); +assert.sameValue(result.value, 1, 'First result `value`'); +assert.sameValue(result.done, false, 'First result `done` flag'); + +result = iter.next(3); +assert.sameValue(result.value, 3, 'Second result `value`'); +assert.sameValue(result.done, false, 'Second result `done` flag'); + +result = iter.next(); +assert.sameValue(result.value, undefined, 'Final result `value`'); +assert.sameValue(result.done, true, 'Final result `done`flag'); diff --git a/test/language/statements/generators/has-instance.js b/test/language/statements/generators/has-instance.js new file mode 100644 index 0000000000..ddf9d239a5 --- /dev/null +++ b/test/language/statements/generators/has-instance.js @@ -0,0 +1,13 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + A Generator object is an instance of a generator function. +es6id: 25.3 +---*/ + +function* g() {} + +assert(g() instanceof g, 'Instance created via function invocation'); +assert(new g() instanceof g, 'Instance created via constructor invocation'); diff --git a/test/language/statements/generators/length-property-descriptor.js b/test/language/statements/generators/length-property-descriptor.js new file mode 100644 index 0000000000..cfd6ef940e --- /dev/null +++ b/test/language/statements/generators/length-property-descriptor.js @@ -0,0 +1,16 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Generator functions should define a `length` property. +includes: [propertyHelper.js] +es6id: 25.2.4 +---*/ + +function* g() {} + +assert.sameValue(g.length, 0); +verifyNotEnumerable(g, 'length'); +verifyNotWritable(g, 'length'); +verifyConfigurable(g, 'length'); diff --git a/test/language/statements/generators/name-property-descriptor.js b/test/language/statements/generators/name-property-descriptor.js new file mode 100644 index 0000000000..f3e8007c8f --- /dev/null +++ b/test/language/statements/generators/name-property-descriptor.js @@ -0,0 +1,16 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Generator functions should define a `name` property. +includes: [propertyHelper.js] +es6id: 25.2.4 +---*/ + +function* g() {} + +assert.sameValue(g.name, 'g'); +verifyNotEnumerable(g, 'name'); +verifyNotWritable(g, 'name'); +verifyConfigurable(g, 'name'); diff --git a/test/language/statements/generators/prototype-property-descriptor.js b/test/language/statements/generators/prototype-property-descriptor.js new file mode 100644 index 0000000000..1ab7fbc3ba --- /dev/null +++ b/test/language/statements/generators/prototype-property-descriptor.js @@ -0,0 +1,15 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Generator objects should define a `prototype` property. +includes: [propertyHelper.js] +es6id: 25.2.4 +---*/ + +function* g() {} + +verifyNotEnumerable(g, 'prototype'); +verifyWritable(g, 'prototype'); +verifyNotConfigurable(g, 'prototype'); diff --git a/test/language/statements/generators/prototype-relation-to-function.js b/test/language/statements/generators/prototype-relation-to-function.js new file mode 100644 index 0000000000..8966bbae76 --- /dev/null +++ b/test/language/statements/generators/prototype-relation-to-function.js @@ -0,0 +1,17 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + The value of the [[Prototype]] internal slot of the GeneratorFunction + prototype object is the FunctionPrototype intrinsic object. +es6id: 25.2.2.2 +---*/ + +function f() {} +function* g() {} + +assert.sameValue( + Object.getPrototypeOf(Object.getPrototypeOf(g)), + Object.getPrototypeOf(f) +); diff --git a/test/language/statements/generators/prototype-typeof.js b/test/language/statements/generators/prototype-typeof.js new file mode 100644 index 0000000000..1f2fa3de20 --- /dev/null +++ b/test/language/statements/generators/prototype-typeof.js @@ -0,0 +1,12 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 25.2.4.2 +description: > + Whenever a GeneratorFunction instance is created another ordinary object is + also created and is the initial value of the generator function’s prototype + property. +---*/ + +function* g() {} +assert.sameValue(typeof g.prototype, 'object'); diff --git a/test/language/statements/generators/prototype-uniqueness.js b/test/language/statements/generators/prototype-uniqueness.js new file mode 100644 index 0000000000..91b00a3ca1 --- /dev/null +++ b/test/language/statements/generators/prototype-uniqueness.js @@ -0,0 +1,13 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + GeneratorFunction instances are created with a unique prototype object. +es6id: 25.2.1 +---*/ + +function* g1() {} +function* g2() {} + +assert(g1.prototype !== g2.prototype); diff --git a/test/language/statements/generators/prototype-value.js b/test/language/statements/generators/prototype-value.js new file mode 100644 index 0000000000..c74f8ccad0 --- /dev/null +++ b/test/language/statements/generators/prototype-value.js @@ -0,0 +1,23 @@ +// Copyright (C) 2013 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Generator instances directly inherit properties from the object that is the + value of the prototype property of the Generator function that created the + instance. +es6id: 25.3 +---*/ + +function* g() {} + +assert.sameValue( + Object.getPrototypeOf(g()), + g.prototype, + 'Instance created via function invocation' +); +assert.sameValue( + Object.getPrototypeOf(new g()), + g.prototype, + 'Instance created via constructor invocation' +);