const { branchLike } = this.props;
const { measures } = this.state;
const query = parseQuery(this.props.location.query);
- const hasOverview = hasFullMeasures(branchLike);
- const displayOverview = hasOverview && hasBubbleChart(query.metric);
+ const showFullMeasures = hasFullMeasures(branchLike);
+ const displayOverview = hasBubbleChart(query.metric);
const metric = this.getSelectedMetric(query, displayOverview);
return (
<div className="layout-page-side-inner">
<div className="layout-page-filters">
<Sidebar
- hasOverview={hasOverview}
measures={measures}
selectedMetric={metric ? metric.key : query.metric}
+ showFullMeasures={showFullMeasures}
updateQuery={this.updateQuery}
/>
</div>
<span className="measure-details-value spacer-left">
<strong>
<Measure
- className={isDiff ? 'leak-box' : undefined}
+ className={isDiff && displayLeak ? 'leak-box' : undefined}
metricKey={metric.key}
metricType={metric.type}
value={measureValue}
import MeasureContentHeader from './MeasureContentHeader';
import PageActions from '../../../components/ui/PageActions';
import BubbleChart from '../drilldown/BubbleChart';
+import DeferredSpinner from '../../../components/common/DeferredSpinner';
import SourceViewer from '../../../components/SourceViewer/SourceViewer';
import { getComponentLeaves } from '../../../api/components';
-import { enhanceComponent, getBubbleMetrics, isFileType } from '../utils';
+import { enhanceComponent, getBubbleMetrics, isFileType, hasFullMeasures } from '../utils';
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branches';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
interface Props {
branchLike?: T.BranchLike;
render() {
const { branchLike, component, leakPeriod, rootComponent } = this.props;
const { paging } = this.state;
+ const displayLeak = hasFullMeasures(branchLike);
return (
<div className={this.props.className}>
<div className="layout-page-header-panel layout-page-main-header">
</div>
<div className="layout-page-main-inner measure-details-content">
<div className="clearfix big-spacer-bottom">
- {leakPeriod && (
- <LeakPeriodLegend className="pull-right" component={component} period={leakPeriod} />
- )}
+ {leakPeriod &&
+ displayLeak && (
+ <LeakPeriodLegend
+ className="pull-right"
+ component={component}
+ period={leakPeriod}
+ />
+ )}
</div>
<DeferredSpinner loading={this.props.loading} />
{!this.props.loading && this.renderContent()}
interface Props {
domain: { name: string; measures: T.MeasureEnhanced[] };
- hasOverview: boolean;
onChange: (metric: string) => void;
onToggle: (property: string) => void;
open: boolean;
selected: string;
+ showFullMeasures: boolean;
}
export default class DomainFacet extends React.PureComponent<Props> {
};
hasOverview = (domain: string) => {
- return this.props.hasOverview && hasBubbleChart(domain);
+ return this.props.showFullMeasures && hasBubbleChart(domain);
};
renderItemFacetStat = (item: T.MeasureEnhanced) => {
- return hasFacetStat(item.metric.key) ? <FacetMeasureValue measure={item} /> : null;
+ return hasFacetStat(item.metric.key) ? (
+ <FacetMeasureValue displayLeak={this.props.showFullMeasures} measure={item} />
+ ) : null;
+ };
+
+ renderCategoryItem = (item: string) => {
+ return this.props.showFullMeasures || item === 'new_code_category' ? (
+ <span className="facet search-navigator-facet facet-category" key={item}>
+ <span className="facet-name">{translate('component_measures.facet_category', item)}</span>
+ </span>
+ ) : null;
};
renderItemsFacet = () => {
return sortedItems.map(
item =>
typeof item === 'string' ? (
- <span className="facet search-navigator-facet facet-category" key={item}>
- <span className="facet-name">
- {!this.props.hasOverview && item === 'overall_category'
- ? translate('component_measures.facet_category', item, 'estimated')
- : translate('component_measures.facet_category', item)}
- </span>
- </span>
+ this.renderCategoryItem(item)
) : (
<FacetItem
active={item.metric.key === selected}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import * as classNames from 'classnames';
import Measure from '../../../components/measure/Measure';
import { isDiffMetric } from '../../../helpers/measures';
interface Props {
+ displayLeak?: boolean;
measure: T.MeasureEnhanced;
}
-export default function FacetMeasureValue({ measure }: Props) {
+export default function FacetMeasureValue({ measure, displayLeak }: Props) {
if (isDiffMetric(measure.metric.key)) {
return (
- <div className="domain-measures-value leak-box" id={`measure-${measure.metric.key}-leak`}>
+ <div
+ className={classNames('domain-measures-value', { 'leak-box': displayLeak })}
+ id={`measure-${measure.metric.key}-leak`}>
<Measure
metricKey={measure.metric.key}
metricType={measure.metric.type}
import { groupByDomains, KNOWN_DOMAINS, PROJECT_OVERVEW, Query } from '../utils';
interface Props {
- hasOverview: boolean;
measures: T.MeasureEnhanced[];
selectedMetric: string;
+ showFullMeasures: boolean;
updateQuery: (query: Partial<Query>) => void;
}
};
render() {
- const { hasOverview } = this.props;
+ const { showFullMeasures } = this.props;
return (
<div>
- {hasOverview && (
- <ProjectOverviewFacet
- onChange={this.changeMetric}
- selected={this.props.selectedMetric}
- value={PROJECT_OVERVEW}
- />
- )}
+ <ProjectOverviewFacet
+ onChange={this.changeMetric}
+ selected={this.props.selectedMetric}
+ value={PROJECT_OVERVEW}
+ />
{groupByDomains(this.props.measures).map(domain => (
<DomainFacet
domain={domain}
- hasOverview={hasOverview}
key={domain.name}
onChange={this.changeMetric}
onToggle={this.toggleFacet}
open={this.state.openFacets[domain.name] === true}
selected={this.props.selectedMetric}
+ showFullMeasures={showFullMeasures}
/>
))}
</div>
import { shallow } from 'enzyme';
import DomainFacet from '../DomainFacet';
-const DOMAIN = {
- name: 'Reliability',
- measures: [
- {
- metric: {
- id: '1',
- key: 'bugs',
- type: 'INT',
- name: 'Bugs',
- domain: 'Reliability'
- },
- value: '5',
- periods: [{ index: 1, value: '5' }],
- leak: '5'
- },
- {
- metric: {
- id: '2',
- key: 'new_bugs',
- type: 'INT',
- name: 'New Bugs',
- domain: 'Reliability'
- },
- periods: [{ index: 1, value: '5' }],
- leak: '5'
- }
- ]
-};
-
-const PROPS = {
- domain: DOMAIN,
- hasOverview: true,
- onChange: () => {},
- onToggle: () => {},
- open: true,
- selected: 'foo'
-};
-
it('should display facet item list', () => {
- expect(shallow(<DomainFacet {...PROPS} />)).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot();
});
it('should display facet item list with bugs selected', () => {
- expect(shallow(<DomainFacet {...PROPS} selected="bugs" />)).toMatchSnapshot();
+ expect(shallowRender({ selected: 'bugs' })).toMatchSnapshot();
});
it('should render closed', () => {
- const wrapper = shallow(<DomainFacet {...PROPS} open={false} />);
+ const wrapper = shallowRender({ open: false });
expect(wrapper.find('FacetItemsList')).toHaveLength(0);
});
it('should render without overview', () => {
- const wrapper = shallow(<DomainFacet {...PROPS} hasOverview={false} />);
+ const wrapper = shallowRender({ showFullMeasures: false });
expect(
wrapper
.find('FacetItem')
).toBe(false);
});
-it('should use "estimated" label for overall measures ', () => {
- const wrapper = shallow(<DomainFacet {...PROPS} hasOverview={false} />);
- expect(wrapper.find('.facet-name').map(w => w.text())).toMatchSnapshot();
-});
-
it('should not display subtitles of new measures if there is none', () => {
const domain = {
name: 'Reliability',
]
};
- expect(shallow(<DomainFacet {...PROPS} domain={domain} />)).toMatchSnapshot();
+ expect(shallowRender({ domain })).toMatchSnapshot();
});
it('should not display subtitles of new measures if there is none, even on last line', () => {
]
};
- expect(shallow(<DomainFacet {...PROPS} domain={domain} />)).toMatchSnapshot();
+ expect(shallowRender({ domain })).toMatchSnapshot();
});
+
+function shallowRender(props: Partial<DomainFacet['props']> = {}) {
+ return shallow(
+ <DomainFacet
+ domain={{
+ name: 'Reliability',
+ measures: [
+ {
+ metric: {
+ id: '1',
+ key: 'bugs',
+ type: 'INT',
+ name: 'Bugs',
+ domain: 'Reliability'
+ },
+ value: '5',
+ periods: [{ index: 1, value: '5' }],
+ leak: '5'
+ },
+ {
+ metric: {
+ id: '2',
+ key: 'new_bugs',
+ type: 'INT',
+ name: 'New Bugs',
+ domain: 'Reliability'
+ },
+ periods: [{ index: 1, value: '5' }],
+ leak: '5'
+ }
+ ]
+ }}
+ onChange={() => {}}
+ onToggle={() => {}}
+ open={true}
+ selected={'foo'}
+ showFullMeasures={true}
+ {...props}
+ />
+ );
+}
};
it('should display measure value', () => {
- expect(shallow(<FacetMeasureValue measure={MEASURE} />)).toMatchSnapshot();
+ expect(shallow(<FacetMeasureValue displayLeak={true} measure={MEASURE} />)).toMatchSnapshot();
});
it('should display leak measure value', () => {
- expect(shallow(<FacetMeasureValue measure={LEAK_MEASURE} />)).toMatchSnapshot();
+ expect(
+ shallow(<FacetMeasureValue displayLeak={true} measure={LEAK_MEASURE} />)
+ ).toMatchSnapshot();
+ expect(
+ shallow(<FacetMeasureValue displayLeak={false} measure={LEAK_MEASURE} />)
+ ).toMatchSnapshot();
});
import { shallow } from 'enzyme';
import Sidebar from '../Sidebar';
-const MEASURES = [
- {
- metric: {
- id: '1',
- key: 'lines_to_cover',
- type: 'INT',
- name: 'Lines to Cover',
- domain: 'Coverage'
- },
- value: '431',
- periods: [{ index: 1, value: '70' }],
- leak: '70'
- },
- {
- metric: {
- id: '2',
- key: 'coverage',
- type: 'PERCENT',
- name: 'Coverage',
- domain: 'Coverage'
- },
- value: '99.3',
- periods: [{ index: 1, value: '0.0999999999999943' }],
- leak: '0.0999999999999943'
- },
- {
- metric: {
- id: '3',
- key: 'duplicated_lines_density',
- type: 'PERCENT',
- name: 'Duplicated Lines (%)',
- domain: 'Duplications'
- },
- value: '3.2',
- periods: [{ index: 1, value: '0.0' }],
- leak: '0.0'
- }
-];
-
-const PROPS = {
- hasOverview: true,
- measures: MEASURES,
- selectedMetric: 'duplicated_lines_density',
- updateQuery: () => {}
-};
-
it('should display two facets', () => {
- expect(shallow(<Sidebar {...PROPS} />)).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot();
});
it('should correctly toggle facets', () => {
- const wrapper = shallow<Sidebar>(<Sidebar {...PROPS} />);
+ const wrapper = shallowRender();
expect(wrapper.state('openFacets').bugs).toBeUndefined();
(wrapper.instance() as Sidebar).toggleFacet('bugs');
expect(wrapper.state('openFacets').bugs).toBeTruthy();
(wrapper.instance() as Sidebar).toggleFacet('bugs');
expect(wrapper.state('openFacets').bugs).toBeFalsy();
});
+
+function shallowRender(props = {}) {
+ return shallow<Sidebar>(
+ <Sidebar
+ measures={[
+ {
+ metric: {
+ id: '1',
+ key: 'lines_to_cover',
+ type: 'INT',
+ name: 'Lines to Cover',
+ domain: 'Coverage'
+ },
+ value: '431',
+ periods: [{ index: 1, value: '70' }],
+ leak: '70'
+ },
+ {
+ metric: {
+ id: '2',
+ key: 'coverage',
+ type: 'PERCENT',
+ name: 'Coverage',
+ domain: 'Coverage'
+ },
+ value: '99.3',
+ periods: [{ index: 1, value: '0.0999999999999943' }],
+ leak: '0.0999999999999943'
+ },
+ {
+ metric: {
+ id: '3',
+ key: 'duplicated_lines_density',
+ type: 'PERCENT',
+ name: 'Duplicated Lines (%)',
+ domain: 'Duplications'
+ },
+ value: '3.2',
+ periods: [{ index: 1, value: '0.0' }],
+ leak: '0.0'
+ }
+ ]}
+ selectedMetric={'duplicated_lines_density'}
+ showFullMeasures={true}
+ updateQuery={() => {}}
+ {...props}
+ />
+ );
+}
onClick={[Function]}
stat={
<FacetMeasureValue
+ displayLeak={true}
measure={
Object {
"leak": "5",
onClick={[Function]}
stat={
<FacetMeasureValue
+ displayLeak={true}
measure={
Object {
"leak": "5",
onClick={[Function]}
stat={
<FacetMeasureValue
+ displayLeak={true}
measure={
Object {
"leak": "5",
onClick={[Function]}
stat={
<FacetMeasureValue
+ displayLeak={true}
measure={
Object {
"leak": "5",
onClick={[Function]}
stat={
<FacetMeasureValue
+ displayLeak={true}
measure={
Object {
"metric": Object {
onClick={[Function]}
stat={
<FacetMeasureValue
+ displayLeak={true}
measure={
Object {
"metric": Object {
</FacetItemsList>
</FacetBox>
`;
-
-exports[`should use "estimated" label for overall measures 1`] = `
-Array [
- "component_measures.facet_category.new_code_category",
- "component_measures.facet_category.overall_category.estimated",
-]
-`;
</div>
`;
+exports[`should display leak measure value 2`] = `
+<div
+ className="domain-measures-value"
+ id="measure-new_bugs-leak"
+>
+ <Measure
+ metricKey="new_bugs"
+ metricType="INT"
+ value="5"
+ />
+</div>
+`;
+
exports[`should display measure value 1`] = `
<div
className="domain-measures-value"
"name": "Coverage",
}
}
- hasOverview={true}
key="Coverage"
onChange={[Function]}
onToggle={[Function]}
open={false}
selected="duplicated_lines_density"
+ showFullMeasures={true}
/>
<DomainFacet
domain={
"name": "Duplications",
}
}
- hasOverview={true}
key="Duplications"
onChange={[Function]}
onToggle={[Function]}
open={true}
selected="duplicated_lines_density"
+ showFullMeasures={true}
/>
</div>
`;
import { getLocalizedMetricName } from '../../helpers/l10n';
import { enhanceMeasure } from '../../components/measure/utils';
import { cleanQuery, parseAsString, RawQuery, serializeString } from '../../helpers/query';
-import { isLongLivingBranch, isMainBranch } from '../../helpers/branches';
-import { getDisplayMetrics } from '../../helpers/measures';
+import {
+ isLongLivingBranch,
+ isMainBranch,
+ isPullRequest,
+ isShortLivingBranch
+} from '../../helpers/branches';
+import { getDisplayMetrics, isDiffMetric } from '../../helpers/measures';
export type View = 'list' | 'tree' | 'treemap';
metrics: { [key: string]: T.Metric },
branch?: T.BranchLike
) {
- if (!hasFullMeasures(branch)) {
- return [
- 'coverage',
- 'new_coverage',
- 'new_lines_to_cover',
- 'new_uncovered_lines',
- 'new_line_coverage',
- 'new_conditions_to_cover',
- 'new_uncovered_conditions',
- 'new_branch_coverage',
-
- 'duplicated_lines_density',
- 'new_duplicated_lines_density',
- 'new_duplicated_lines',
- 'new_duplicated_blocks'
- ];
- }
+ const metricKeys = getDisplayMetrics(Object.values(metrics)).map(metric => metric.key);
- return getDisplayMetrics(Object.values(metrics)).map(metric => metric.key);
+ if (isPullRequest(branch) || isShortLivingBranch(branch)) {
+ return metricKeys.filter(key => isDiffMetric(key));
+ } else {
+ return metricKeys;
+ }
}
export function getBubbleMetrics(domain: string, metrics: { [key: string]: T.Metric }) {