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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions