Skip to content

Source generator: CancellationToken declared before a params array on a non-generic test does not receive the test token #7147

Closed

Description

@thomhurst

Summary

On a non-generic test method, a CancellationToken parameter declared before a trailing params array does not receive the test's cancellation token in source-generated mode. Reflection mode injects it correctly, so the two modes disagree.

Repro

public class TokenBeforeParams
{
    [Test]
    [Arguments]
    public async Task M(int count = 42, CancellationToken token = default, params int[] values)
    {
        await Assert.That(token.CanBeCanceled).IsTrue();
    }
}
  • --reflection: passes.
  • Source-generated: fails. The generated invoker treats token as a data parameter and passes default(CancellationToken) (on main the token was simply omitted, with the same result).

Found while working on #7122 (verified on its branch by adding the assertion above to tests/TUnit.TestProject/Bugs/_7122/OmittedOptionalOverloadTests.cs, Optional_Before_Params_With_Token).

Where

TestMetadataGenerator.GetLeadingCancellationTokenIndex and its comment state a non-trailing token is "only reachable for generic methods"; for non-generic methods the token apparently stays in parametersFromArgs. Reflection mode (ReflectionTestMetadata, ~line 112) inserts the token at its declared index for any method.

Expected

Both modes pass the test's cancellation token to a CancellationToken parameter wherever it is declared (or an analyzer rejects non-trailing tokens consistently).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions