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

Allow users to create custom summarizers #612

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

elliot-nelson
Copy link
Contributor

@elliot-nelson elliot-nelson commented May 22, 2021

SUMMARY

Export a new interface that allows users to create their own custom summarize functions, and to use them when building custom reporters for istanbul (or when calling existing reporters). Today this isn't really possible because the user of istanbul-lib-reports can't get access to the underlying structures (like ReportTree) you need to build a summarizer.

An example of how an end-user could use this new interface:

import { create as createReport } from 'istanbul-reports';
import { createContext } from 'istanbul-lib-report';
import { ReportNode, ReportTree, Util, Path } from 'istanbul-lib-report/summarizer';

// Custom summarizer: organize all files into two-deep subfolders from root.
function getTree(initialList, commonParent) {
    const nodeMap = Object.create(null);
    const topPaths = [];
    initialList.forEach(o => {
        const node = new ReportNode(o.path, o.fileCoverage);
        const parent = Util.findOrCreateParent(
            new Path(o.path.elements().slice(0, 2)),
            nodeMap,
            (parentPath, parent) => {
                topPaths.push(parent);
            }
        );
        parent.addChild(node);
    });

    return new ReportTree(ReportNode.createRoot(topPaths));
}

const context = createContext({ /* get a bunch of coverage data */ });
const report = createReport('html', { summarizer: getTree });
report.execute(context);

DETAILS

I've put together my suggested implementation for this feature, a quick change list:

  • Allow the HTML reporter to accept a summarizer option.
  • Break up most of summarizer-factory into summarizer-core, pulling the utility functions into a Util object.
  • Allow the Context to take either a summarizer name, or a summarizer function which will be executed instead.
  • Add a new top-level entry point summarizer.js, which re-exports pieces of summarizer-core.
  • Best-effort new descriptions of the different summarizer pieces and how to use them to create a custom summarizer.
  • I "un-privatized" the _summary field on ReportBase -- I think it's appropriate to allow custom subclasses of ReportBase to override the _summary field in their constructor, after calling the super constructor (or even for an end-user to construct a ReportBase object, and then override the field manually before calling execute().)

TESTING

I've tested this change using my desired new summarizer (see example above for something close to what I'm looking for), and the existing summarizers (pkg, nested, flat). Added unit tests to get code coverage back to 100%, but am happy to add more if there's additional functionality I should test.

@bcoe
Copy link
Member

bcoe commented Dec 29, 2021

@elliot-nelson this seems like a great feature, sorry for the slow review. I'm supportive of this refactor, but would like to test thoroughly with all the existing summarizers on a few of my codebases, since all the reporters do not have good coverage.

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.

None yet

2 participants