Skip to content
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

Cross-references, inline markup, viewcode and documenters #53

Open
cblegare opened this issue Feb 16, 2022 · 7 comments
Open

Cross-references, inline markup, viewcode and documenters #53

cblegare opened this issue Feb 16, 2022 · 7 comments

Comments

@cblegare
Copy link

cblegare commented Feb 16, 2022

Hello there!

Thank you for this nice project. I have a few ideas for improvement. I might be able to contribute a bit, but I think it is better to first discuss them beforehand 👍

  • Viewcode

    It might be interesting to embed the Gherkin code in the rendered HTML, just like the sphinx.ext.viewcode extension.
    See it in action in your own documentation.

  • Cross references from the glossary

    As of now, the generated Glossary lists file paths and line numbers.
    In addition to possibly link to code lines (using the Viewcode idea above), it could be interesting to link to the generated Gherkin RST entry.

    This might involve introducing a couple new Directives, but it opens to nice possibilities, including having the features, files (and other objects of interest) exposed in the objects.inv file thus cross-reference-able from other documentations using Intersphinx

    Also, along with a Glossary, Sphinx provide Domain Indices (see Domains) to help gather references to things of interest that belong together.

  • Markup for keywords

    In order to improve readability, the Gherkin keywords (Given, Then, etc) could be bold or something.

  • Documenters

    While a tad more complex, including the Gherkin definitions using Directives instead of generating whole files would be quite great. The implementation would likely look like a simplified version of autodoc

What do you think about these? Would you be willing to review and merge contributions?

@dgou
Copy link
Contributor

dgou commented Feb 17, 2022

Thanks for the feedback and ideas!

Re: the Viewcode option, I'm not sure how I feel about that. I'm not against it, per se, but I'm not gung ho about it either, I will defer to the rest of the team on this one.

Re: Cross reference for the glossary - YES! This is something that has been a pet idea of mine for a long time, but never rose to the level of being important enough to pursue. Domains are an interesting idea, but I'm not sure I get how to make them work without adding additional markup to the Gherkin which I really really want to avoid. One idea I have thought a lot about is harvesting data from the step definitions themselves, but that can be tricky since, for example, behave and pytest-bdd handle that in different ways, and that is all within Python, let alone other implementation languages.
tl;dr I am highly interested in more specific ideas about this. (The cross reference glossary has been near and dear to my heart for a long time.)

Re: Markup for keywords is already in place, you can use .CSS files per https://github.com/jolly-good-toolbelt/sphinx_gherkindoc#formatting-options

Re: Documenters - it's late enough that something about this isn't clicking for me, I'll need fresher eyes and maybe a skosh more detail...

@cblegare
Copy link
Author

cblegare commented Feb 17, 2022

Hey, that was fast, thanks!

Viewcode

This one might is indeed less appealing, also, I am not sure how the pygment lexer would behave with different implementations of the language. Lets forget about this one then, at least for now.

Markup

Sorry about that one. You got us covered!

Documenters

You can manually place the documentation for ,say, a python class by using the .. class:: some.Class directive. Sphinx then finds the definition, reads the function name and arguments and docstring and generate the docutil nodes, which in turn are rendered. I'll get back to this below.

Documenters build whole documents including the directives, but let's put that aside for the moment.

Cross-references

Let me have a look deeper down how sphinx_gherkindoc models all those. I must admit I don't know much about Gherkin, let alone different implementations. I'm simply the guy knowing a thing or two about Sphinx extensions that tries to help a few people. I'll get back with a more solid opinion on the complexity of this, including differences between implementations.

Using directives (and roles) makes it easier to leverage the standard Sphinx APIs to wire together the references.

So instead of generating a document like this:

:gherkin-feature-keyword:`Feature:` :gherkin-feature-content:`Integrated Backgrounds`
=====================================================================================

:gherkin-scenario-keyword:`Scenario:` :gherkin-scenario-content:`First Scenario`
--------------------------------------------------------------------------------

| :gherkin-step-keyword:`Given` a step that is from the background
| :gherkin-step-keyword:`But` the step actually appears with the scenario steps in the sphinx docs
| :gherkin-step-keyword:`Given` a step that is defined in the scenario
| :gherkin-step-keyword:`And` one more for good measure
| :gherkin-step-keyword:`When` I use sphinx-gherkindoc with the --integrate-background flag
| :gherkin-step-keyword:`Then` the background steps should be integrated with the scenario steps

You would instead generate something like

.. gherkin:feature:: Integrated Backgrounds

    Optionaly some descriptive stuff here
    
    .. gherkin:scenario:: First Scenario
    
        .. gherkin:given:: a step that is from the background
        .. gherkin:but:: the step actually appears with the scenario steps in the sphinx docs
        .. gherkin:given:: a step that is defined in the scenario
        .. gherkin:and:: one more for good measure
        .. gherkin:when:: I use sphinx-gherkindoc with the --integrate-background flag
        .. gherkin:then:: the background steps should be integrated with the scenario steps

(that would be one way of doing it)

and having these directives, you can still render the nodes (and HTML/latex), still using the CSS, etc, but also get to hook into the cross-referencing engine.

Of course, cross-referencing roles would be quite verbose, for instance:

For more details, see :gherkin:scenario:`Integrated Background.First Scenario`.

@dgou
Copy link
Contributor

dgou commented Feb 21, 2022

Thank you, it is nice having an external set of Sphinx expertise eyes looking over this.
The cross referencing is... verbose, but it should be mostly machine generated.
One thing related to what we've been discussing, that I have been thinking about for a long time, is also to have a way for steps of the gherkin to be grouped by subject matter (such as all the steps that mention a specific word or phrase). Not as explicit references in the Gherkin files themselves, but perhaps with a side processor or plug-in that would be called with the text of a step (or scenario name or feather name, etc. etc.) and could return a list of "hey, here are the categories that are relevant for this text. (Such as recognizing Persona names, for example, or other aspects of the system under test). In large part the Feature file itself is such a grouping, but as steps are more and more reused, its nice to have a way to find where all the steps that reference concept - X are.

But, back to the most immediate topic(? I think ?) instead of having the glossary listing files and line numbers, you're suggesting using the directives as targets for links, and have the glossary use the cross-reference roles. That is something that, at least pre-coffee monday morning, makes sense to me. :)

@cblegare
Copy link
Author

The cross referencing is... verbose, but it should be mostly machine generated.

Yes, it is. In fact, that markup would have more chances to be hand-written than the above directives. It can be shortened though

  • The domain can be skipped with configuration or a directive at the top of the file:

    .. default-domain:: gherkin
    
    For more details, see :scenario:`Integrated Background.First Scenario`.

    See Domain basic markup

  • The "interpreted text" part could also be shorter, but it needs enough to find the cross reference target. If you use epic numbers for features and issue numbers for scenarios, it could be as short as

    For more details, see :scenario:`12.345`.

    (this trumps the idea of readable documentation as plaintext)

    If scenario names are unique across features (which could be the case), we could omit the feature name (and raise a warning/error if it needs more details to find the right scenario):

    For more details, see :scenario:`First Scenario`.

    There is also a possibility to ensure the :any: role works (which tries to cross references only based on the "interpreted text" part

    For more details, see :any:`First Scenario`.

Once you have directives and domain data, all of the above are quite simple to put in place.


steps of the gherkin to be grouped by subject matter

This is again a nice use-case for a domain Index. Since a given domain can provide multiple indexes, and the base strings to search in steps could come from configuration or directives.


instead of having the glossary listing files and line numbers, you're suggesting using the directives as targets for links, and have the glossary use the cross-reference roles.

At least to get started, and in order to go easy on this package's users, both could be available.


To sum up, I'll look into ways of making the Sphinx application aware of the gherkin features and scenarios as soon I get the chance. Then, wiring things together with configs and directives is not that complicated, and the Indices need only to feed on Domain data.

I'm still busy with another project of mine (have a look if you're a Terraform user ;) Sphinx-Terraform) but I expect to have a bit of free time in the next few weeks.

@cblegare
Copy link
Author

I've skimmed through the gherkin parser implementation.

Once I get the chance, I'll try with a basic extension:

  • create a Sphinx extension (a module with a setup function)
  • mimick the CLI arguments, but for conf.py
  • cram a dictionary with the result from the parsers and store it in the build env
  • re-wire the writers so they use directives, but optionaly for backward compatibility I guess.

@cblegare
Copy link
Author

Hi there!

I ended up writing it on the side: https://cblegare.gitlab.io/sphinx-gherkin/

It misses a lot of feature sphinx_gherkindoc provides, but has some the the things we discussed above. The main difference is that I built it with the Sphinx extension API in mind from the start

@dgou
Copy link
Contributor

dgou commented Mar 26, 2022

Interesting. Some how the email notification of your comment ended up in my junk folder, sorry for the delay!

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

No branches or pull requests

2 participants