Gutenberg: Auto-generated unit tests from JSDoc

Created on 20 May 2019  路  10Comments  路  Source: WordPress/gutenberg

Description

We are using JSDoc's @example token as of today to include code examples with the usage of public API methods. The issue is that those examples can get out of date and it won't get noticed until someone reports it. I'd like us to seek to improve this workflow and introduce internal auto-generated unit tests for those examples which could also play a role of better documentation at the same time.

_Example:_

/**
 * Count some words.
 *
 * @param {String} text         The text being processed
 * @param {String} type         The type of count. Accepts ;words', 'characters_excluding_spaces', or 'characters_including_spaces'.
 * @param {Object} userSettings Custom settings object.
 *
 * @example
 * ```js
 * import { count } from '@wordpress/wordcount';
 * const numberOfWords = count( 'Words to count', 'words', {} )
 * ```
 *
 * @return {Number} The word or character count.
 */
export function count( text, type, userSettings ) {
    if ( '' === text ) {
        return 0;
    }

    if ( text ) {
        const settings = loadSettings( type, userSettings );
        const matchRegExp = settings[ type + 'RegExp' ];
        const results = ( 'words' === settings.type ) ?
            matchWords( text, matchRegExp, settings ) :
            matchCharacters( text, matchRegExp, settings );

        return results ? results.length : 0;
    }
}

Proposal

_Update: Edited based on feedback from @aduth in https://github.com/WordPress/gutenberg/issues/15735#issuecomment-493971244._

Add handling for the result of operation assigned to result constant in @example JSDoc token:

/**
 * @example
 * ```js
 * import { count } from '@wordpress/wordcount';
 * count( 'Words to count', 'words', {} );
 * // => 3
 * ```
 */

Behind the scenes, we would generate test files in a similar way we do it for documentation. In the case of @wordpress/wordcount package we could create packages/wordcount/src/test/public-api.jsdoc.js file, hoist and deduplicates all imports (we should allow only imports from WordPress packages for simplicity) and wrap everything else with description and test. In addition, the code comment with return value would be used to create assertion matcher.

Example:

// `public-api.jsdoc.js` - this file is auto-generated with `npm run docs:build`.
import { count } from '@wordpress/wordcount';

description( 'wordcount - public API', () => {
    test( 'count', () => {
        const result = count( 'Words to count', 'words', {} );
        expect( result ).toBe( 3 );
    } );
} );
Automated Testing Needs Dev [Type] Documentation [Type] Task

Most helpful comment

See this for inspiration https://github.com/hoaproject/Kitab (cc @Hywan)

All 10 comments

See this for inspiration https://github.com/hoaproject/Kitab (cc @Hywan)

@youknowriad shared also this npm package in our private discussion:
https://yamadapc.github.io/jsdoctest
It integrates with Mocha but provides the same functionality I was thinking about.

Also for inspiration: python has something like this.

This would be great.

A few questions on specifics:

  • Would these expected results be included anywhere in the documentation? I actually quite like the jsdoctest example where the conventional // => expected result could be used both for documentation and for constructing a test case. At the very least, from the provided proposal, the expected 3 value would be nice to include somewhere in the documented example.
  • I wonder if we still might _run_ the code for examples without the expected result, to at least check against runtime errors (which would be quite likely in cases where code has become outdated).
  • Would these expected results be included anywhere in the documentation? I actually quite like the jsdoctest example where the conventional // => expected result could be used both for documentation and for constructing a test case. At the very least, from the provided proposal, the expected 3 value would be nice to include somewhere in the documented example.

This seems like a great proposal as we could operate using @example exclusively 馃憤
I will update the description according to your proposal.

  • I wonder if we still might _run_ the code for examples without the expected result, to at least check against runtime errors (which would be quite likely in cases where code has become outdated).

Yes, we totally could do that as well 馃憤

Related https://github.com/WordPress/gutenberg/pull/18031. StoryShots is very similar but for stories written for Storybook. This will solve the issue for UI components.

It should be tackled after #21238 is merged.

It should be tackled after #21238 is merged.

Awesome, @sainthkh let me know when you have PR opened or is it that you wanted to highlight the dependency? 馃槃

Actually both. I wanted to highlight the dependency to make sure some volunteers mistakenly try to implement this before #21238 is done.

And I also want to tackle it myself, too.

Even prior to implementing any automation, it seems like a related task would be to ensure there's consistency in the existing documentation for how these "expected results" values are notated. My earlier comment https://github.com/WordPress/gutenberg/issues/15735#issuecomment-493971244 mentioned the // => convention. If we want to settle on this, we can already start to update existing code samples today, which would make future integration more seamless, and also bring some consistency to auto-documentation.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BE-Webdesign picture BE-Webdesign  路  3Comments

spocke picture spocke  路  3Comments

moorscode picture moorscode  路  3Comments

franz-josef-kaiser picture franz-josef-kaiser  路  3Comments

aduth picture aduth  路  3Comments