aboutsummaryrefslogtreecommitdiff
path: root/node_modules/istanbul-reports/lib/html-spa/src
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/istanbul-reports/lib/html-spa/src')
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/fileBreadcrumbs.js31
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/filterToggle.js50
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/flattenToggle.js25
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/getChildData.js155
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/index.js160
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/routing.js52
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/summaryHeader.js63
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/summaryTableHeader.js130
-rw-r--r--node_modules/istanbul-reports/lib/html-spa/src/summaryTableLine.js159
9 files changed, 825 insertions, 0 deletions
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/fileBreadcrumbs.js b/node_modules/istanbul-reports/lib/html-spa/src/fileBreadcrumbs.js
new file mode 100644
index 0000000..b123d37
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/fileBreadcrumbs.js
@@ -0,0 +1,31 @@
+const React = require('react');
+
+module.exports = function FileBreadcrumbs({ fileFilter = '', setFileFilter }) {
+ const parts = fileFilter.split('/');
+ const breadcrumbs = [
+ {
+ path: '',
+ name: 'all files'
+ },
+ ...parts.map((part, i) => ({
+ path: parts.slice(0, i + 1).join('/'),
+ name: part
+ }))
+ ];
+
+ return breadcrumbs.map(({ path, name }) =>
+ path === fileFilter ? (
+ name
+ ) : (
+ <>
+ <a
+ href="javascript:void(0)"
+ onClick={() => setFileFilter(path)}
+ >
+ {name}
+ </a>
+ /
+ </>
+ )
+ );
+};
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/filterToggle.js b/node_modules/istanbul-reports/lib/html-spa/src/filterToggle.js
new file mode 100644
index 0000000..b636b53
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/filterToggle.js
@@ -0,0 +1,50 @@
+const React = require('react');
+
+function ToggleOption({ children, filter, activeFilters, setFilters }) {
+ return (
+ <button
+ className={
+ 'toggle__option ' + (activeFilters[filter] ? 'is-toggled' : '')
+ }
+ onClick={() =>
+ setFilters({
+ ...activeFilters,
+ [filter]: !activeFilters[filter]
+ })
+ }
+ >
+ {children}
+ </button>
+ );
+}
+
+module.exports = function FilterToggle({ activeFilters, setFilters }) {
+ return (
+ <div className="toggle">
+ <div className="toggle__label">Filter:</div>
+ <div className="toggle__options">
+ <ToggleOption
+ filter="low"
+ activeFilters={activeFilters}
+ setFilters={setFilters}
+ >
+ Low
+ </ToggleOption>
+ <ToggleOption
+ filter="medium"
+ activeFilters={activeFilters}
+ setFilters={setFilters}
+ >
+ Medium
+ </ToggleOption>
+ <ToggleOption
+ filter="high"
+ activeFilters={activeFilters}
+ setFilters={setFilters}
+ >
+ High
+ </ToggleOption>
+ </div>
+ </div>
+ );
+};
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/flattenToggle.js b/node_modules/istanbul-reports/lib/html-spa/src/flattenToggle.js
new file mode 100644
index 0000000..8bb6ea3
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/flattenToggle.js
@@ -0,0 +1,25 @@
+const React = require('react');
+
+module.exports = function FlattenButton({ setIsFlat, isFlat }) {
+ return (
+ <div className="toggle">
+ <div className="toggle__label">Files:</div>
+ <div className="toggle__options">
+ <button
+ onClick={() => setIsFlat(!isFlat)}
+ className={
+ 'toggle__option ' + (!isFlat ? 'is-toggled' : '')
+ }
+ >
+ Tree
+ </button>
+ <button
+ onClick={() => setIsFlat(!isFlat)}
+ className={'toggle__option ' + (isFlat ? 'is-toggled' : '')}
+ >
+ Flat
+ </button>
+ </div>{' '}
+ </div>
+ );
+};
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/getChildData.js b/node_modules/istanbul-reports/lib/html-spa/src/getChildData.js
new file mode 100644
index 0000000..eff5d31
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/getChildData.js
@@ -0,0 +1,155 @@
+function addPath(node, parentPath) {
+ if (!parentPath) {
+ return node;
+ }
+ return { ...node, file: parentPath + '/' + node.file };
+}
+
+function flatten(nodes, parentPath) {
+ let children = [];
+ for (let i = 0; i < nodes.length; i++) {
+ const child = nodes[i];
+ if (child.children) {
+ children = [
+ ...children,
+ ...flatten(
+ child.children,
+ (parentPath ? parentPath + '/' : '') + child.file
+ )
+ ];
+ } else {
+ children.push(addPath(child, parentPath));
+ }
+ }
+ return children;
+}
+
+function filterByFile(nodes, fileFilter, parentPath) {
+ let children = [];
+
+ for (let i = 0; i < nodes.length; i++) {
+ const child = nodes[i];
+ const childFullPath = (parentPath ? parentPath + '/' : '') + child.file;
+
+ const isChildUnderFilter =
+ fileFilter === childFullPath ||
+ fileFilter.indexOf(childFullPath + '/') === 0;
+ const isChildAboveFilter =
+ childFullPath.indexOf(fileFilter + '/') === 0;
+
+ if (isChildUnderFilter) {
+ // flatten and continue looking underneath
+ children = [
+ ...children,
+ ...filterByFile(child.children, fileFilter, childFullPath)
+ ];
+ } else if (isChildAboveFilter) {
+ // remove the parent path and add everything underneath
+ const charsToRemoveFromFile =
+ fileFilter.length - (parentPath ? parentPath.length : 0);
+ let childFilename = child.file.slice(charsToRemoveFromFile);
+ if (childFilename[0] === '/') {
+ childFilename = childFilename.slice(1);
+ }
+ children.push({
+ ...child,
+ file: childFilename
+ });
+ }
+ }
+ return children;
+}
+
+function sort(childData, activeSort) {
+ const top = activeSort.order === 'asc' ? 1 : -1;
+ const bottom = activeSort.order === 'asc' ? -1 : 1;
+ childData.sort((a, b) => {
+ let valueA;
+ let valueB;
+ if (activeSort.sortKey === 'file') {
+ valueA = a.file;
+ valueB = b.file;
+ } else {
+ const [metricType, valueType] = activeSort.sortKey.split('.');
+ valueA = a.metrics[metricType][valueType];
+ valueB = b.metrics[metricType][valueType];
+ }
+
+ if (valueA === valueB) {
+ return 0;
+ }
+ return valueA < valueB ? top : bottom;
+ });
+
+ for (let i = 0; i < childData.length; i++) {
+ const child = childData[i];
+ if (child.children) {
+ childData[i] = {
+ ...child,
+ children: sort(child.children, activeSort)
+ };
+ }
+ }
+ return childData;
+}
+
+function filter(nodes, metricsMap, activeFilters) {
+ const children = [];
+ for (let i = 0; i < nodes.length; i++) {
+ let child = nodes[i];
+ if (child.children) {
+ const newSubChildren = filter(
+ child.children,
+ metricsMap,
+ activeFilters
+ );
+ if (newSubChildren.length) {
+ child = { ...child, children: newSubChildren };
+ children.push(child);
+ }
+ } else {
+ if (
+ (metricsMap.statements &&
+ activeFilters[child.metrics.statements.classForPercent]) ||
+ (metricsMap.branches &&
+ activeFilters[child.metrics.branches.classForPercent]) ||
+ (metricsMap.functions &&
+ activeFilters[child.metrics.functions.classForPercent]) ||
+ (metricsMap.lines &&
+ activeFilters[child.metrics.lines.classForPercent])
+ ) {
+ children.push(child);
+ }
+ }
+ }
+ return children;
+}
+
+module.exports = function getChildData(
+ sourceData,
+ metricsToShow,
+ activeSort,
+ isFlat,
+ activeFilters,
+ fileFilter
+) {
+ let childData = sourceData.children;
+
+ if (isFlat) {
+ childData = flatten(childData.slice(0));
+ }
+
+ if (fileFilter) {
+ childData = filterByFile(childData, fileFilter);
+ }
+
+ if (activeFilters.low) {
+ activeFilters = { ...activeFilters, empty: true };
+ }
+ childData = filter(childData, metricsToShow, activeFilters);
+
+ if (activeSort) {
+ childData = sort(childData, activeSort);
+ }
+ return childData;
+};
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/index.js b/node_modules/istanbul-reports/lib/html-spa/src/index.js
new file mode 100644
index 0000000..c89c416
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/index.js
@@ -0,0 +1,160 @@
+// The index file for the spa running on the summary page
+const React = require('react');
+const ReactDOM = require('react-dom');
+const SummaryTableHeader = require('./summaryTableHeader');
+const SummaryTableLine = require('./summaryTableLine');
+const SummaryHeader = require('./summaryHeader');
+const getChildData = require('./getChildData');
+const FlattenToggle = require('./flattenToggle');
+const FilterToggle = require('./filterToggle');
+const FileBreadcrumbs = require('./fileBreadcrumbs');
+const { setLocation, decodeLocation } = require('./routing');
+
+const { useState, useMemo, useEffect } = React;
+
+const sourceData = window.data;
+const metricsToShow = {};
+for (let i = 0; i < window.metricsToShow.length; i++) {
+ metricsToShow[window.metricsToShow[i]] = true;
+}
+
+let firstMount = true;
+
+function App() {
+ const routingDefaults = decodeLocation();
+
+ const [activeSort, setSort] = useState(
+ (routingDefaults && routingDefaults.activeSort) || {
+ sortKey: 'file',
+ order: 'desc'
+ }
+ );
+ const [isFlat, setIsFlat] = useState(
+ (routingDefaults && routingDefaults.isFlat) || false
+ );
+ const [activeFilters, setFilters] = useState(
+ (routingDefaults && routingDefaults.activeFilters) || {
+ low: true,
+ medium: true,
+ high: true
+ }
+ );
+ const [expandedLines, setExpandedLines] = useState(
+ (routingDefaults && routingDefaults.expandedLines) || []
+ );
+ const [fileFilter, setFileFilter] = useState(
+ (routingDefaults && routingDefaults.fileFilter) || ''
+ );
+ const childData = useMemo(
+ () =>
+ getChildData(
+ sourceData,
+ metricsToShow,
+ activeSort,
+ isFlat,
+ activeFilters,
+ fileFilter
+ ),
+ [activeSort, isFlat, activeFilters, fileFilter]
+ );
+ const overallMetrics = sourceData.metrics;
+
+ useEffect(() => {
+ setLocation(
+ firstMount,
+ activeSort,
+ isFlat,
+ activeFilters,
+ fileFilter,
+ expandedLines
+ );
+ firstMount = false;
+ }, [activeSort, isFlat, activeFilters, fileFilter, expandedLines]);
+
+ useEffect(() => {
+ window.onpopstate = () => {
+ const routingState = decodeLocation();
+ if (routingState) {
+ // make sure all the state is set before rendering to avoid url updates
+ // alternative is to merge all the states into one so it can be set in one go
+ // https://github.com/facebook/react/issues/14259
+ ReactDOM.unstable_batchedUpdates(() => {
+ setFilters(routingState.activeFilters);
+ setSort(routingState.activeSort);
+ setIsFlat(routingState.isFlat);
+ setExpandedLines(routingState.expandedLines);
+ setFileFilter(routingState.fileFilter);
+ });
+ }
+ };
+ }, []);
+
+ return (
+ <div className="layout">
+ <div className="layout__section">
+ <SummaryHeader
+ metrics={overallMetrics}
+ metricsToShow={metricsToShow}
+ />
+ </div>
+ <div className="layout__section">
+ <div className="toolbar">
+ <div className="toolbar__item">
+ <FlattenToggle setIsFlat={setIsFlat} isFlat={isFlat} />
+ </div>
+ <div className="toolbar__item">
+ <FilterToggle
+ activeFilters={activeFilters}
+ setFilters={setFilters}
+ />
+ </div>
+ </div>
+ </div>
+ <div className="layout__section">
+ <h1>
+ <FileBreadcrumbs
+ fileFilter={fileFilter}
+ setFileFilter={setFileFilter}
+ />
+ </h1>
+ </div>
+ <div className="layout__section layout__section--fill">
+ <table className="coverage-summary">
+ <SummaryTableHeader
+ onSort={newSort => {
+ setSort(newSort);
+ }}
+ activeSort={activeSort}
+ metricsToShow={metricsToShow}
+ />
+ <tbody>
+ {childData.map(child => (
+ <SummaryTableLine
+ {...child}
+ key={child.file}
+ metricsToShow={metricsToShow}
+ expandedLines={expandedLines}
+ setExpandedLines={setExpandedLines}
+ fileFilter={fileFilter}
+ setFileFilter={setFileFilter}
+ />
+ ))}
+ </tbody>
+ </table>
+ </div>
+ <div className="layout__section center small quiet">
+ Code coverage generated by{' '}
+ <a
+ href="https://istanbul.js.org/"
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ istanbul
+ </a>{' '}
+ at {window.generatedDatetime}
+ </div>
+ </div>
+ );
+}
+
+ReactDOM.render(<App />, document.getElementById('app'));
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/routing.js b/node_modules/istanbul-reports/lib/html-spa/src/routing.js
new file mode 100644
index 0000000..a4d0bc7
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/routing.js
@@ -0,0 +1,52 @@
+exports.setLocation = function setLocation(
+ isReplace,
+ activeSort,
+ isFlat,
+ activeFilters,
+ fileFilter,
+ expandedLines
+) {
+ const params = [
+ activeSort.sortKey,
+ activeSort.order,
+ isFlat,
+ activeFilters.low,
+ activeFilters.medium,
+ activeFilters.high,
+ encodeURIComponent(fileFilter),
+ expandedLines.map(encodeURIComponent).join(',')
+ ];
+ const newUrl = `#${params.join('/')}`;
+
+ if (newUrl === location.hash) {
+ return;
+ }
+
+ window.history[isReplace ? 'replaceState' : 'pushState'](null, '', newUrl);
+};
+
+exports.decodeLocation = function decodeLocation() {
+ const items = location.hash.substr(1).split('/');
+ if (items.length !== 8) {
+ return null;
+ }
+
+ try {
+ return {
+ activeSort: {
+ sortKey: items[0],
+ order: items[1]
+ },
+ isFlat: JSON.parse(items[2]),
+ activeFilters: {
+ low: JSON.parse(items[3]),
+ medium: JSON.parse(items[4]),
+ high: JSON.parse(items[5])
+ },
+ fileFilter: decodeURIComponent(items[6]),
+ expandedLines: items[7].split(',').map(decodeURIComponent)
+ };
+ } catch (e) {
+ return null;
+ }
+};
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/summaryHeader.js b/node_modules/istanbul-reports/lib/html-spa/src/summaryHeader.js
new file mode 100644
index 0000000..3bdd8ff
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/summaryHeader.js
@@ -0,0 +1,63 @@
+const React = require('react');
+
+function Ignores({ metrics, metricsToShow }) {
+ const metricKeys = Object.keys(metricsToShow);
+ const result = [];
+
+ for (let i = 0; i < metricKeys.length; i++) {
+ const metricKey = metricKeys[i];
+ if (metricsToShow[metricKey]) {
+ const skipped = metrics[metricKey].skipped;
+ if (skipped > 0) {
+ result.push(
+ `${skipped} ${metricKey}${
+ skipped === 1 ? '' : metricKey === 'branch' ? 'es' : 's'
+ }`
+ );
+ }
+ }
+ }
+
+ if (result.length === 0) {
+ return false;
+ }
+
+ return (
+ <div className="toolbar__item">
+ <span className="strong">{result.join(', ')}</span>
+ <span className="quiet">Ignored</span>
+ </div>
+ );
+}
+
+function StatusMetric({ data, name }) {
+ return (
+ <div className="toolbar__item">
+ <span className="strong">{data.pct}%</span>{' '}
+ <span className="quiet">{name}</span>{' '}
+ <span className={'fraction ' + data.classForPercent}>
+ {data.covered}/{data.total}
+ </span>
+ </div>
+ );
+}
+
+module.exports = function SummaryHeader({ metrics, metricsToShow }) {
+ return (
+ <div className="toolbar">
+ {metricsToShow.statements && (
+ <StatusMetric data={metrics.statements} name="Statements" />
+ )}
+ {metricsToShow.branches && (
+ <StatusMetric data={metrics.branches} name="Branches" />
+ )}
+ {metricsToShow.functions && (
+ <StatusMetric data={metrics.functions} name="Functions" />
+ )}
+ {metricsToShow.lines && (
+ <StatusMetric data={metrics.lines} name="Lines" />
+ )}
+ <Ignores metrics={metrics} metricsToShow={metricsToShow} />
+ </div>
+ );
+};
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/summaryTableHeader.js b/node_modules/istanbul-reports/lib/html-spa/src/summaryTableHeader.js
new file mode 100644
index 0000000..7cf964e
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/summaryTableHeader.js
@@ -0,0 +1,130 @@
+const React = require('react');
+
+function getSortDetails(sortKey, activeSort) {
+ let newSort = { sortKey, order: 'desc' };
+ let sortClass = '';
+ if (activeSort && activeSort.sortKey === sortKey) {
+ sortClass = 'sorted';
+ if (activeSort.order === 'desc') {
+ sortClass += '-desc';
+ newSort.order = 'asc';
+ } else {
+ if (sortKey !== 'file') {
+ newSort = { sortKey: 'file', order: 'desc' };
+ }
+ }
+ }
+
+ return {
+ newSort,
+ sortClass
+ };
+}
+
+function SummaryTableHeaderCell({ name, onSort, sortKey, activeSort }) {
+ const { newSort, sortClass } = getSortDetails(sortKey, activeSort);
+ return (
+ <th
+ className={'sortable headercell ' + sortClass}
+ onClick={() => onSort(newSort)}
+ >
+ {name}
+ <span className="sorter" />
+ </th>
+ );
+}
+
+function FileHeaderCell({ onSort, activeSort }) {
+ const { newSort, sortClass } = getSortDetails('file', activeSort);
+
+ return (
+ <th
+ className={'sortable file ' + sortClass}
+ onClick={() => onSort(newSort)}
+ >
+ File
+ <span className="sorter" />
+ </th>
+ );
+}
+
+function SubHeadings({ sortKeyPrefix, onSort, activeSort }) {
+ return (
+ <>
+ <SummaryTableHeaderCell
+ name="%"
+ onSort={onSort}
+ sortKey={sortKeyPrefix + '.pct'}
+ activeSort={activeSort}
+ />
+ <th className="headercell"></th>
+ <SummaryTableHeaderCell
+ name="Covered"
+ onSort={onSort}
+ sortKey={sortKeyPrefix + '.covered'}
+ activeSort={activeSort}
+ />
+ <SummaryTableHeaderCell
+ name="Missed"
+ onSort={onSort}
+ sortKey={sortKeyPrefix + '.missed'}
+ activeSort={activeSort}
+ />
+ <SummaryTableHeaderCell
+ name="Total"
+ onSort={onSort}
+ sortKey={sortKeyPrefix + '.total'}
+ activeSort={activeSort}
+ />
+ </>
+ );
+}
+
+module.exports = function SummaryTableHeader({
+ onSort,
+ activeSort,
+ metricsToShow
+}) {
+ return (
+ <thead>
+ <tr className="topheading">
+ <th></th>
+ {metricsToShow.statements && <th colSpan={4}>Statements</th>}
+ {metricsToShow.branches && <th colSpan={4}>Branches</th>}
+ {metricsToShow.functions && <th colSpan={4}>Functions</th>}
+ {metricsToShow.lines && <th colSpan={4}>Lines</th>}
+ </tr>
+ <tr className="subheading">
+ <FileHeaderCell onSort={onSort} activeSort={activeSort} />
+ {metricsToShow.statements && (
+ <SubHeadings
+ sortKeyPrefix="statements"
+ onSort={onSort}
+ activeSort={activeSort}
+ />
+ )}
+ {metricsToShow.branches && (
+ <SubHeadings
+ sortKeyPrefix="branches"
+ onSort={onSort}
+ activeSort={activeSort}
+ />
+ )}
+ {metricsToShow.functions && (
+ <SubHeadings
+ sortKeyPrefix="functions"
+ onSort={onSort}
+ activeSort={activeSort}
+ />
+ )}
+ {metricsToShow.lines && (
+ <SubHeadings
+ sortKeyPrefix="lines"
+ onSort={onSort}
+ activeSort={activeSort}
+ />
+ )}
+ </tr>
+ </thead>
+ );
+};
diff --git a/node_modules/istanbul-reports/lib/html-spa/src/summaryTableLine.js b/node_modules/istanbul-reports/lib/html-spa/src/summaryTableLine.js
new file mode 100644
index 0000000..6dc56e6
--- /dev/null
+++ b/node_modules/istanbul-reports/lib/html-spa/src/summaryTableLine.js
@@ -0,0 +1,159 @@
+const React = require('react');
+
+function MetricCells({ metrics }) {
+ const { classForPercent, pct, covered, missed, total } = metrics;
+
+ return (
+ <>
+ <td className={'pct ' + classForPercent}>{Math.round(pct)}% </td>
+ <td className={classForPercent}>
+ <div className="bar">
+ <div
+ className={`bar__data ${classForPercent} ${classForPercent}--dark`}
+ style={{ width: pct + '%' }}
+ ></div>
+ </div>
+ </td>
+ <td className={'abs ' + classForPercent}>{covered}</td>
+ <td className={'abs ' + classForPercent}>{missed}</td>
+ <td className={'abs ' + classForPercent}>{total}</td>
+ </>
+ );
+}
+
+function FileCell({
+ file,
+ prefix,
+ expandedLines,
+ setExpandedLines,
+ hasChildren,
+ setFileFilter
+}) {
+ if (hasChildren) {
+ const expandedIndex = expandedLines.indexOf(prefix + file);
+ const isExpanded = expandedIndex >= 0;
+ const newExpandedLines = isExpanded
+ ? [
+ ...expandedLines.slice(0, expandedIndex),
+ ...expandedLines.slice(expandedIndex + 1)
+ ]
+ : [...expandedLines, prefix + file];
+
+ return (
+ <>
+ <button
+ type="button"
+ onClick={() => setExpandedLines(newExpandedLines)}
+ className="expandbutton"
+ >
+ {isExpanded ? String.fromCharCode(0x2013) : '+'}
+ </button>
+ <a
+ href="javascript:void(0)"
+ onClick={() => setFileFilter(prefix + file)}
+ >
+ {file}
+ </a>
+ </>
+ );
+ } else {
+ return <a href={`./${prefix}${file}.html`}>{file}</a>;
+ }
+}
+
+function getWorstMetricClassForPercent(metricsToShow, metrics) {
+ let classForPercent = 'none';
+ for (const metricToShow in metricsToShow) {
+ if (metricsToShow[metricToShow]) {
+ const metricClassForPercent = metrics[metricToShow].classForPercent;
+
+ // ignore none metrics so they don't change whats shown
+ if (metricClassForPercent === 'none') {
+ continue;
+ }
+
+ // if the metric low or lower than whats currently being used, replace it
+ if (
+ metricClassForPercent == 'low' ||
+ (metricClassForPercent === 'medium' &&
+ classForPercent !== 'low') ||
+ (metricClassForPercent === 'high' &&
+ classForPercent !== 'low' &&
+ classForPercent !== 'medium')
+ ) {
+ classForPercent = metricClassForPercent;
+ }
+ }
+ }
+ return classForPercent;
+}
+
+module.exports = function SummaryTableLine({
+ prefix,
+ metrics,
+ file,
+ children,
+ tabSize,
+ metricsToShow,
+ expandedLines,
+ setExpandedLines,
+ fileFilter,
+ setFileFilter
+}) {
+ tabSize = tabSize || 0;
+ if (children && tabSize > 0) {
+ tabSize--;
+ }
+ prefix = (fileFilter ? fileFilter + '/' : '') + (prefix || '');
+
+ return (
+ <>
+ <tr>
+ <td
+ className={
+ 'file ' +
+ getWorstMetricClassForPercent(metricsToShow, metrics)
+ }
+ >
+ {/* eslint-disable-line prefer-spread */ Array.apply(null, {
+ length: tabSize
+ }).map((nothing, index) => (
+ <span className="filetab" key={index} />
+ ))}
+ <FileCell
+ file={file}
+ prefix={prefix}
+ expandedLines={expandedLines}
+ setExpandedLines={setExpandedLines}
+ hasChildren={Boolean(children)}
+ setFileFilter={setFileFilter}
+ />
+ </td>
+ {metricsToShow.statements && (
+ <MetricCells metrics={metrics.statements} />
+ )}
+ {metricsToShow.branches && (
+ <MetricCells metrics={metrics.branches} />
+ )}
+ {metricsToShow.functions && (
+ <MetricCells metrics={metrics.functions} />
+ )}
+ {metricsToShow.lines && <MetricCells metrics={metrics.lines} />}
+ </tr>
+ {children &&
+ expandedLines.indexOf(prefix + file) >= 0 &&
+ children.map(child => (
+ <SummaryTableLine
+ {...child}
+ tabSize={tabSize + 2}
+ key={child.file}
+ prefix={prefix + file + '/'}
+ metricsToShow={metricsToShow}
+ expandedLines={expandedLines}
+ setExpandedLines={setExpandedLines}
+ setFileFilter={setFileFilter}
+ />
+ ))}
+ </>
+ );
+};