Skip to content

Async Generator flow control tests #871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is return, and generator.[[AsyncGeneratorState]] is
"suspendedStart", generator is closed without being resumed.

AsyncGeneratorResolve will unwrap Promise values (steps 6-10)
flags: [async]
---*/

var g = async function*() {
throw new Test262Error('Generator must not be resumed.');
};

var it = g();
var resolve;
var promise = new Promise(function(resolver) {
resolve = resolver;
});

it.return(promise).then(function(ret) {
assert.sameValue(ret.value, 'unwrapped-value', 'AsyncGeneratorResolve(generator, completion.[[Value]], true)');
assert.sameValue(ret.done, true, 'AsyncGeneratorResolve(generator, completion.[[Value]], true)');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);
}).catch($DONE);

resolve('unwrapped-value');
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is return, and generator.[[AsyncGeneratorState]] is
"suspendedStart", generator is closed without being resumed.
flags: [async]
---*/

var g = async function*() {
throw new Test262Error('Generator must not be resumed.');
};

var it = g();
it.return('sent-value').then(function(ret) {
assert.sameValue(ret.value, 'sent-value', 'AsyncGeneratorResolve(generator, completion.[[Value]], true)');
assert.sameValue(ret.done, true, 'AsyncGeneratorResolve(generator, completion.[[Value]], true)');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);
}).catch($DONE);
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is return, and generator.[[AsyncGeneratorState]] is
"suspendedYield", generator is resumed and immediately closes the generator
and returns completion.
flags: [async]
---*/

var g = async function*() {
yield 1;
throw new Test262Error('Generator must not be resumed.');
};

var it = g();
var resolve;
var promise = new Promise(function(resolver) {
resolve = resolver;
});
it.next().then(function(ret) {
assert.sameValue(ret.value, 1, 'Initial yield');
assert.sameValue(ret.done, false, 'Initial yield');

it.return(promise).then(function(ret) {
assert.sameValue(ret.value, 'unwrapped-value', 'AsyncGeneratorResolve(generator, resultValue, true)');
assert.sameValue(ret.done, true, 'AsyncGeneratorResolve(generator, resultValue, true)');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);

}).catch($DONE);

resolve('unwrapped-value');
}).catch($DONE);
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is return, and generator.[[AsyncGeneratorState]] is
"suspendedYield", and generator is resumed within a try-block with an
associated finally block, resume execution within finally.
flags: [async]
---*/

var g = async function*() {
try {
yield 1;
throw new Test262Error('Generator must be resumed in finally block.');
} finally {
return 'done';
}
};

var it = g();
it.next().then(function(ret) {
assert.sameValue(ret.value, 1, 'Initial yield');
assert.sameValue(ret.done, false, 'Initial yield');

it.return('sent-value').then(function(ret) {
assert.sameValue(ret.value, 'done', 'AsyncGeneratorResolve(generator, resultValue, true)');
assert.sameValue(ret.done, true, 'AsyncGeneratorResolve(generator, resultValue, true)');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);

}).catch($DONE);

}).catch($DONE);
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is return, and generator.[[AsyncGeneratorState]] is
"suspendedYield", and generator is resumed within a try-block with an
associated finally block, resume execution within finally.
flags: [async]
---*/

var error = new Error("boop");
var g = async function*() {
try {
yield 1;
throw new Test262Error('Generator must be resumed in finally block.');
} finally {
throw error;
throw new Test262Error('Generator must not be resumed.');
}
};

var it = g();
it.next().then(function(ret) {
assert.sameValue(ret.value, 1, 'Initial yield');
assert.sameValue(ret.done, false, 'Initial yield');

it.return('sent-value').then($DONE, function(err) {
assert.sameValue(err, error, 'AsyncGeneratorReject(generator, resultValue)');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);

}).catch($DONE);

}).catch($DONE);
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is return, and generator.[[AsyncGeneratorState]] is
"suspendedYield", and generator is resumed within a try-block with an
associated finally block, resume execution within finally.
flags: [async]
---*/

var g = async function*() {
try {
yield 1;
throw new Test262Error('Generator must be resumed in finally block.');
} finally {
yield 2;
}
};

var it = g();
it.next().then(function(ret) {
assert.sameValue(ret.value, 1, 'Initial yield');
assert.sameValue(ret.done, false, 'Initial yield');

it.return('sent-value').then(function(ret) {
assert.sameValue(ret.value, 2, 'Yield in finally block');
assert.sameValue(ret.done, false, 'Yield in finally block');

it.next().then(function(ret) {
assert.sameValue(ret.value, 'sent-value', 'AsyncGeneratorResolve(generator, resultValue, true)');
assert.sameValue(ret.done, true, 'AsyncGeneratorResolve(generator, resultValue, true)');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);

}).catch($DONE);

}).catch($DONE);

}).catch($DONE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish we could have Promise#finally already

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it would help with the nested Promises

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason these are nested instead of chained anyway?

it.next()
.then(function(ret) {
  assert.sameValue(ret.value, 1, 'Initial yield');
  assert.sameValue(ret.done, false, 'Initial yield');

  return it.return('sent-value');
})
.then(function(ret) {
  assert.sameValue(ret.value, 2, 'Yield in finally block');
  assert.sameValue(ret.done, false, 'Yield in finally block');

  return it.next();
})
.then(function(ret) {
  assert.sameValue(ret.value, 'sent-value', 'AsyncGeneratorResolve(generator, resultValue, true)');
  assert.sameValue(ret.done, true, 'AsyncGeneratorResolve(generator, resultValue, true)');

  return it.next();
})
.then(function(ret) {
  assert.sameValue(ret.value, undefined, 'Generator is closed');
  assert.sameValue(ret.done, true, 'Generator is closed');
})
.then($DONE, $DONE);

Copy link
Contributor Author

@caitp caitp Mar 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(returning a Promise and chaining is) harder to read, less obvious, etc

Copy link
Contributor

@gnarf gnarf Mar 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I very much disagree, 4 level nested callbacks are much less readable than chaining promises, but I also don't care enough to block, it seems you've reached "annoyed" point on this PR (been there myself, sorry if I'm projecting) and I don't want to add to it any more. Thanks for the contribution!

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is return, and generator.[[AsyncGeneratorState]] is
"suspendedYield", generator is resumed and immediately closes the generator
and returns completion.
flags: [async]
---*/

var g = async function*() {
yield 1;
throw new Test262Error('Generator must not be resumed.');
};

var it = g();
it.next().then(function(ret) {
assert.sameValue(ret.value, 1, 'Initial yield');
assert.sameValue(ret.done, false, 'Initial yield');

it.return('sent-value').then(function(ret) {
assert.sameValue(ret.value, 'sent-value', 'AsyncGeneratorResolve(generator, resultValue, true)');
assert.sameValue(ret.done, true, 'AsyncGeneratorResolve(generator, resultValue, true)');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);

}).catch($DONE);

}).catch($DONE);
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is throw, and generator.[[AsyncGeneratorState]] is
"suspendedStart", generator is closed without being resumed.

AsyncGeneratorReject will not unwrap Promise values
flags: [async]
---*/

var g = async function*() {
throw new Test262Error('Generator must not be resumed.');
};

var it = g();
var promise = new Promise(function() {});

it.throw(promise).then($DONE, function(err) {
assert.sameValue(err, promise, 'AsyncGeneratorReject(generator, completion.[[Value]])');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);
}).catch($DONE);
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is throw, and generator.[[AsyncGeneratorState]] is
"suspendedStart", generator is closed without being resumed.
flags: [async]
---*/

var error = new Error('boop');
var g = async function*() {
throw new Test262Error('Generator must not be resumed.');
};

var it = g();
it.throw(error).then($DONE, function(err) {
assert.sameValue(err, error, 'AsyncGeneratorReject(generator, completion.[[Value]])');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);
}).catch($DONE);
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
author: Caitlin Potter <[email protected]>
esid: pending
description: >
AsyncGeneratorResumeNext:
If completion.[[Type]] is throw, and generator.[[AsyncGeneratorState]] is
"suspendedYield", generator is resumed and immediately and
closes the generator and returns completion.

AsyncGeneratorReject will not unwrap Promise values
flags: [async]
---*/

var g = async function*() {
yield 1;
throw new Test262Error('Generator must not be resumed.');
};

var it = g();
var promise = new Promise(function() {});

it.next().then(function(ret) {
assert.sameValue(ret.value, 1, 'Initial yield');
assert.sameValue(ret.done, false, 'Initial yield');

it.throw(promise).then($DONE, function(err) {
assert.sameValue(err, promise, 'AsyncGeneratorReject(generator, resultValue)');

it.next().then(function(ret) {
assert.sameValue(ret.value, undefined, 'Generator is closed');
assert.sameValue(ret.done, true, 'Generator is closed');
}).then($DONE, $DONE);

}).catch($DONE);

}).catch($DONE);
Loading