+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { mockQualityGateStatusCondition } from '../../../helpers/mocks/quality-gates';
-import { mockMeasureEnhanced, mockMetric } from '../../../helpers/testMocks';
-import { MetricKey } from '../../../types/metrics';
-import { getThreshold } from '../utils';
-
-// eslint-disable-next-line no-console
-console.error = jest.fn();
-
-describe('getThreshold', () => {
- it('return undefined if condition is not found', () => {
- expect(getThreshold([], '')).toBeUndefined();
- expect(getThreshold([mockMeasure()], '')).toBeUndefined();
- expect(
- getThreshold(
- [
- {
- metric: mockMetric({ key: MetricKey.quality_gate_details }),
- value: 'badly typed json should fail'
- }
- ],
- ''
- )
- ).toBeUndefined();
- // eslint-disable-next-line no-console
- expect(console.error).toBeCalled();
- });
-
- it('should return the threshold for the right metric', () => {
- expect(getThreshold([mockMeasure()], MetricKey.new_coverage)).toBe(85);
- expect(getThreshold([mockMeasure()], MetricKey.new_duplicated_lines_density)).toBe(5);
- });
-});
-
-function mockMeasure() {
- return mockMeasureEnhanced({
- metric: mockMetric({ key: MetricKey.quality_gate_details }),
- value: JSON.stringify({
- conditions: [
- mockQualityGateStatusCondition({
- metric: MetricKey.new_coverage,
- level: 'ERROR',
- error: '85'
- }),
- mockQualityGateStatusCondition({
- metric: MetricKey.new_duplicated_lines_density,
- level: 'OK',
- warning: '5'
- })
- ]
- })
- });
-}
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import {
- formatMeasure,
- getMinDecimalsCountToBeDistinctFromThreshold
-} from 'sonar-ui-common/helpers/measures';
+import { formatMeasure } from 'sonar-ui-common/helpers/measures';
import { getLeakValue } from '../../../components/measure/utils';
import DrilldownLink from '../../../components/shared/DrilldownLink';
import { findMeasure } from '../../../helpers/measures';
getMeasurementLabelKeys,
getMeasurementLinesMetricKey,
getMeasurementMetricKey,
- getThreshold,
MeasurementType
} from '../utils';
className="overview-measures-value text-light"
component={component.key}
metric={metric}>
- {formatMeasure(value, 'PERCENT', {
- decimals: getMinDecimalsCountToBeDistinctFromThreshold(
- parseFloat(value),
- getThreshold(measures, metric)
- )
- })}
+ {formatMeasure(value, 'PERCENT', { decimals: 2, omitExtraDecimalZeros: true })}
</DrilldownLink>
);
const label = this.getLabelText();
import { Link } from 'react-router';
import IssueTypeIcon from 'sonar-ui-common/components/icons/IssueTypeIcon';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import {
- formatMeasure,
- getMinDecimalsCountToBeDistinctFromThreshold
-} from 'sonar-ui-common/helpers/measures';
+import { formatMeasure } from 'sonar-ui-common/helpers/measures';
import Measure from '../../../components/measure/Measure';
import DrilldownLink from '../../../components/shared/DrilldownLink';
import { getBranchLikeQuery } from '../../../helpers/branch-like';
: measure.value) as string;
let operator = translate('quality_gates.operator', condition.op);
- let decimals: number | undefined = undefined;
if (metric.type === 'RATING') {
operator = translate('quality_gates.operator', condition.op, 'rating');
- } else if (metric.type === 'PERCENT') {
- decimals = getMinDecimalsCountToBeDistinctFromThreshold(
- parseFloat(actual),
- parseFloat(threshold)
- );
}
return this.wrapWithLink(
<div className="overview-quality-gate-condition-container display-flex-center">
<div className="overview-quality-gate-condition-value text-center">
<Measure
- decimals={decimals}
+ decimals={2}
metricKey={measure.metric.key}
metricType={measure.metric.type}
value={actual}
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="new_maintainability_rating"
metricType="RATING"
value="3"
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="new_open_issues"
metricType="INT"
value="3"
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="new_reliability_rating"
metricType="RATING"
value="3"
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="new_security_rating"
metricType="RATING"
value="3"
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="open_issues"
metricType="INT"
value="3"
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="reliability_rating"
metricType="RATING"
value="3"
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="security_rating"
metricType="RATING"
value="3"
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="new_maintainability_rating"
metricType="RATING"
value="3"
className="overview-quality-gate-condition-value text-center"
>
<Measure
+ decimals={2}
metricKey="sqale_rating"
metricType="RATING"
value="3"
import { translate } from 'sonar-ui-common/helpers/l10n';
import CoverageRating from '../../components/ui/CoverageRating';
import { MetricKey } from '../../types/metrics';
-import { QualityGateStatusConditionEnhanced } from '../../types/quality-gates';
export const METRICS: string[] = [
// quality gate
labelKey: MEASUREMENTS_MAP[type].labelKey
};
}
-
-/*
- * Extract a specific metric's threshold from the quality gate details
- */
-export function getThreshold(
- measures: T.MeasureEnhanced[],
- metricKey: MetricKey | string
-): number | undefined {
- const detailsMeasure = measures.find(
- measure => measure.metric.key === MetricKey.quality_gate_details
- );
- if (detailsMeasure && detailsMeasure.value) {
- const details = safeParse(detailsMeasure.value);
- const conditions: QualityGateStatusConditionEnhanced[] = details.conditions || [];
-
- const condition = conditions.find(c => c.metric === metricKey);
- if (condition) {
- return parseFloat(
- (condition.level === 'ERROR' ? condition.error : condition.warning) as string
- );
- }
- }
- return undefined;
-}
-
-function safeParse(json: string) {
- try {
- return JSON.parse(json);
- } catch (e) {
- // eslint-disable-next-line no-console
- console.error(e);
- return {};
- }
-}
}
if (metricType !== 'RATING') {
- const formattedValue = formatMeasure(value, metricType, { decimals });
+ const formattedValue = formatMeasure(value, metricType, {
+ decimals,
+ omitExtraDecimalZeros: metricType === 'PERCENT'
+ });
return <span className={className}>{formattedValue != null ? formattedValue : '–'}</span>;
}