Skip to content

Missing tests for yield in finally block of a generator #4937

@taras

Description

@taras

Hi there,

This test suite is missing tests for the following use cases

Basic case: Generator paused at yield in try, .return() is called, finally block has a yield that should suspend the generator before completing.

function* g() {
  try {
    yield "in-try";      // paused here
  } finally {
    yield "in-finally";  // .return() should suspend here
  }
}

Nested finally blocks: Both inner and outer finally blocks have yields. All yields must execute in order before the generator completes.

function* g() {
  try {
    try {
      yield "work";
    } finally {
      yield "inner-cleanup";
    }
  } finally {
    yield "outer-cleanup";
  }
}

Resume value: The value passed to .next() while suspended at a yield in finally should be received by that yield expression.

function* g() {
  try {
    yield "work";
  } finally {
    const received = yield "cleanup";  // .next("ack") passes "ack" here
  }
}

Throw before yield: If the finally block throws before reaching a yield, the exception should propagate (standard finally-throw behavior).

function* g() {
  try {
    yield "work";
  } finally {
    throw new Error("cleanup-failed");  // no yield reached
  }
}

Throw after yield: Generator suspends at yield in finally, then when resumed, throws an exception. The exception should propagate.

function* g() {
  try {
    yield "work";
  } finally {
    yield "cleanup";                         // suspends here
    throw new Error("failed-after-yield");   // throws when resumed
  }
}

yield* in finally: When finally contains yield delegating to another generator, all delegated values should be yielded before completing.*

function* cleanup() {
  yield "cleanup-1";
  yield "cleanup-2";
}

function* g() {
  try {
    yield "work";
  } finally {
    yield* cleanup();  // both values yielded during .return()
  }
}

yield* delegation with inner finally: Outer generator delegates to inner generator via yield. When .return() is called, the inner generator's finally block (with yield) must execute.*

function* inner() {
  try {
    yield "inner-work";
  } finally {
    yield "inner-cleanup";
  }
}
function* outer() {
  try {
    yield* inner();
  } finally {
    yield "outer-cleanup";
  }
}

Return in finally overrides: If the finally block contains a return statement, it overrides the value passed to .return().

function* g() {
  try {
    yield "work";
  } finally {
    return "override";  // overrides .return(42) → result is "override"
  }
}

I have a branch with these tests.

I verified all of these tests on Chromium, Firefox and Webkit in Playwright.

May I create a PR against this repo for these tests?

Related grafana/sobek#115 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions