Skip to content

Roslyn Analyzers and Compile-Time Binding Registry #541

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

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

Code-Grump
Copy link
Contributor

🤔 What's changed?

This branch contains multiple Roslyn-centric extensions for Reqnroll. The implementation is basic and only covers the C# language, but could be extended to do more.

  • Added suite of analysers to identify common problems with step bindings:

    • StepMethodMustReturnVoidOrTaskAnalyzer: ensures a step method must return Task or void - all other return types flag an error.
    • AsyncStepMethodMustReturnTaskAnalyzer: ensures a step method marked with the async keyword must also return a Task - all other return types are invalid.
    • StepTextAnalyzer: looks at the step text applied in a step attribute:
      • Ensures the text pattern is not null or an empty string
      • Raises a warning if the step text pattern has leading or trailing whitespace
  • Added a generator which produces a step registry for an assembly being built: a class which contains a set of metadata of all the methods decorated with step definition attributes:

  • Added types to the Reqnroll core library to support expressing a step definition registry as a collection of metadata.

⚡️ What's your motivation?

This work is based on the discussion https://github.com/orgs/reqnroll/discussions/208

Knowing about problems at runtime is fine, but discovering them during authoring is better!

🏷️ What kind of change is this?

  • ⚡ New feature (non-breaking change which adds new behaviour)

♻️ Anything particular you want feedback on?

📋 Checklist:

  • I've changed the behaviour of the code
    • I have added/updated tests to cover my changes.
  • My change requires a change to the documentation.
    • I have updated the documentation accordingly.
  • Users should know about my change
    • I have added an entry to the "[vNext]" section of the CHANGELOG, linking to this pull request & included my GitHub handle to the release contributors list.

This text was originally taken from the template of the Cucumber project, then edited by hand. You can modify the template here.

@304NotModified
Copy link
Contributor

304NotModified commented Mar 29, 2025

Great stuff!

I haven't checked the code, but only read the pull request description

One small note:

  • StepMethodMustReturnVoidOrTaskAnalyzer: ensures a step method must return Task or void - all other return types flag an error.
  • AsyncStepMethodMustReturnTaskAnalyzer: ensures a step method marked with the async keyword must also return a Task - all other return types are invalid.

AFAIK ValueTask is also supported.

And is a separate repo not a better idea for the analyzers?

@Code-Grump
Copy link
Contributor Author

Code-Grump commented Mar 29, 2025

AFAIK ValueTask is also supported.

I based this off the constraints in our documentation. If ValueTask is supported, the documentation should probably be updated to reflect that. In principal we could support any awaitable return type, but I'm just going based on the docs.

And is a separate repo not a better idea for the analyzers?

I have no strong feelings on repo structure. I'd expected both analyzer and generator pieces to be shipped with the core libraries in the same way xunit does, which makes me prefer a single repository. I'm generally in favour of monolithic repos though, which can absolutely colour my judgement.

@304NotModified
Copy link
Contributor

304NotModified commented Mar 29, 2025

I based this off the constraints in our documentation. If ValueTask is supported, the documentation should probably be updated to reflect that

See https://docs.reqnroll.net/latest/guides/migrating-from-specflow.html

Features
...
Support for ValueTask and ValueTask binding methods (step definitions, hooks, step argument transformations)

And about:

I'm generally in favour of monolithic repos though, which can absolutely colour my judgement.

In my experience mono repos move slower (more time to merge prs, more time when released), but it's just a suggestion :)

@Code-Grump
Copy link
Contributor Author

Code-Grump commented Mar 30, 2025

Unfortunately, that's not reflected in the documentation regarding step definitions:
https://docs.reqnroll.net/latest/automation/step-definitions.html

Step Definition Methods Rules

  • Must be in a public class, marked with the [Binding] attribute.
  • Must be a public method.
  • Can be either a static or an instance method. If it is an instance method, the containing class will be instantiated once for every scenario.
  • Cannot have out or ref parameters.
  • Cannot have optional parameters.
  • Should return void or Task. Note async methods must return Task

@goblinmaks
Copy link

#394

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants