]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10471 Improve leak period description for specific date
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Fri, 17 Aug 2018 07:54:44 +0000 (09:54 +0200)
committerSonarTech <sonartech@sonarsource.com>
Mon, 20 Aug 2018 18:21:03 +0000 (20:21 +0200)
16 files changed:
server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.js [deleted file]
server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/component-measures/components/__tests__/LeakPeriodLegend-test.js [deleted file]
server/sonar-web/src/main/js/apps/component-measures/components/__tests__/LeakPeriodLegend-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/LeakPeriodLegend-test.js.snap [deleted file]
server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/LeakPeriodLegend-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.js [deleted file]
server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx
server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.js [deleted file]
server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/LeakPeriodLegend-test.js.snap [deleted file]
server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/LeakPeriodLegend-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/main/enhance.tsx
server/sonar-web/src/main/js/helpers/periods.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.js b/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.js
deleted file mode 100644 (file)
index c2a3227..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import classNames from 'classnames';
-import DateFromNow from '../../../components/intl/DateFromNow';
-import DateFormatter from '../../../components/intl/DateFormatter';
-import Tooltip from '../../../components/controls/Tooltip';
-import { getPeriodLabel, getPeriodDate } from '../../../helpers/periods';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-/*:: import type { Component, Period } from '../types'; */
-
-/*:: type Props = {
-  className?: string,
-  component: Component,
-  period: Period
-}; */
-
-export default function LeakPeriodLegend({ className, component, period } /*: Props */) {
-  const leakClass = classNames('domain-measures-leak-header', className);
-  if (component.qualifier === 'APP') {
-    return <div className={leakClass}>{translate('issues.new_code_period')}</div>;
-  }
-
-  const label = (
-    <div className={leakClass}>
-      {translateWithParameters('overview.new_code_period_x', getPeriodLabel(period))}
-    </div>
-  );
-
-  if (period.mode === 'days') {
-    return label;
-  }
-
-  const date = getPeriodDate(period);
-  const tooltip = (
-    <div>
-      <DateFromNow date={date} />
-      {', '}
-      <DateFormatter date={date} long={true} />
-    </div>
-  );
-  return <Tooltip overlay={tooltip}>{label}</Tooltip>;
-}
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx
new file mode 100644 (file)
index 0000000..bed6f18
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as React from 'react';
+import * as classNames from 'classnames';
+import DateFromNow from '../../../components/intl/DateFromNow';
+import DateFormatter from '../../../components/intl/DateFormatter';
+import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
+import Tooltip from '../../../components/controls/Tooltip';
+import { getPeriodLabel, getPeriodDate, Period, PeriodMode } from '../../../helpers/periods';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { differenceInDays } from '../../../helpers/dates';
+import { ComponentMeasure } from '../../../app/types';
+
+interface Props {
+  className?: string;
+  component: ComponentMeasure;
+  period: Period;
+}
+
+export default function LeakPeriodLegend({ className, component, period }: Props) {
+  const leakClass = classNames('domain-measures-leak-header', className);
+  if (component.qualifier === 'APP') {
+    return <div className={leakClass}>{translate('issues.new_code_period')}</div>;
+  }
+
+  const leakPeriodLabel = getPeriodLabel(period);
+  if (!leakPeriodLabel) {
+    return null;
+  }
+
+  const label = (
+    <div className={leakClass}>
+      {translateWithParameters('overview.new_code_period_x', leakPeriodLabel)}
+    </div>
+  );
+
+  if (period.mode === PeriodMode.days) {
+    return label;
+  }
+
+  const date = getPeriodDate(period);
+  const tooltip = date && (
+    <div>
+      <DateFromNow date={date} />
+      {', '}
+      {differenceInDays(new Date(), date) < 1 ? (
+        <DateTimeFormatter date={date} />
+      ) : (
+        <DateFormatter date={date} long={true} />
+      )}
+    </div>
+  );
+
+  return <Tooltip overlay={tooltip}>{label}</Tooltip>;
+}
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/LeakPeriodLegend-test.js b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/LeakPeriodLegend-test.js
deleted file mode 100644 (file)
index 43e8ef1..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 React from 'react';
-import { shallow } from 'enzyme';
-import LeakPeriodLegend from '../LeakPeriodLegend';
-
-const PROJECT = {
-  key: 'foo',
-  qualifier: 'TRK'
-};
-
-const APP = {
-  key: 'bar',
-  qualifier: 'APP'
-};
-
-const PERIOD = {
-  date: '2017-05-16T13:50:02+0200',
-  index: 1,
-  mode: 'previous_version',
-  parameter: '6,4'
-};
-
-const PERIOD_DAYS = {
-  date: '2017-05-16T13:50:02+0200',
-  index: 1,
-  mode: 'days',
-  parameter: '18'
-};
-
-it('should render correctly', () => {
-  expect(shallow(<LeakPeriodLegend component={PROJECT} period={PERIOD} />)).toMatchSnapshot();
-  expect(shallow(<LeakPeriodLegend component={PROJECT} period={PERIOD_DAYS} />)).toMatchSnapshot();
-});
-
-it('should render correctly for APP', () => {
-  expect(shallow(<LeakPeriodLegend component={APP} period={PERIOD} />)).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/LeakPeriodLegend-test.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/LeakPeriodLegend-test.tsx
new file mode 100644 (file)
index 0000000..90ff902
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as React from 'react';
+import { shallow } from 'enzyme';
+import LeakPeriodLegend from '../LeakPeriodLegend';
+import { PeriodMode } from '../../../../helpers/periods';
+import { differenceInDays } from '../../../../helpers/dates';
+
+jest.mock('../../../../helpers/dates', () => {
+  const dates = require.requireActual('../../../../helpers/dates');
+  dates.differenceInDays = jest.fn().mockReturnValue(10);
+  return dates;
+});
+
+const PROJECT = {
+  key: 'foo',
+  name: 'Foo',
+  qualifier: 'TRK'
+};
+
+const APP = {
+  key: 'bar',
+  name: 'Bar',
+  qualifier: 'APP'
+};
+
+const PERIOD = {
+  date: '2017-05-16T13:50:02+0200',
+  index: 1,
+  mode: PeriodMode.previousVersion,
+  parameter: '6,4'
+};
+
+const PERIOD_DAYS = {
+  date: '2017-05-16T13:50:02+0200',
+  index: 1,
+  mode: PeriodMode.days,
+  parameter: '18'
+};
+
+it('should render correctly', () => {
+  expect(shallow(<LeakPeriodLegend component={PROJECT} period={PERIOD} />)).toMatchSnapshot();
+  expect(shallow(<LeakPeriodLegend component={PROJECT} period={PERIOD_DAYS} />)).toMatchSnapshot();
+});
+
+it('should render correctly for APP', () => {
+  expect(shallow(<LeakPeriodLegend component={APP} period={PERIOD} />)).toMatchSnapshot();
+});
+
+it('should render a more precise date', () => {
+  (differenceInDays as jest.Mock<any>).mockReturnValueOnce(0);
+  expect(shallow(<LeakPeriodLegend component={PROJECT} period={PERIOD} />)).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/LeakPeriodLegend-test.js.snap b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/LeakPeriodLegend-test.js.snap
deleted file mode 100644 (file)
index f5d95db..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Tooltip
-  overlay={
-    <div>
-      <DateFromNow
-        date={2017-05-16T11:50:02.000Z}
-      />
-      , 
-      <DateFormatter
-        date={2017-05-16T11:50:02.000Z}
-        long={true}
-      />
-    </div>
-  }
->
-  <div
-    className="domain-measures-leak-header"
-  >
-    overview.new_code_period_x.overview.period.previous_version.6,4
-  </div>
-</Tooltip>
-`;
-
-exports[`should render correctly 2`] = `
-<div
-  className="domain-measures-leak-header"
->
-  overview.new_code_period_x.overview.period.days.18
-</div>
-`;
-
-exports[`should render correctly for APP 1`] = `
-<div
-  className="domain-measures-leak-header"
->
-  issues.new_code_period
-</div>
-`;
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/LeakPeriodLegend-test.tsx.snap b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/LeakPeriodLegend-test.tsx.snap
new file mode 100644 (file)
index 0000000..09d9f2e
--- /dev/null
@@ -0,0 +1,62 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render a more precise date 1`] = `
+<Tooltip
+  overlay={
+    <div>
+      <DateFromNow
+        date={2017-05-16T11:50:02.000Z}
+      />
+      , 
+      <DateTimeFormatter
+        date={2017-05-16T11:50:02.000Z}
+      />
+    </div>
+  }
+>
+  <div
+    className="domain-measures-leak-header"
+  >
+    overview.new_code_period_x.overview.period.previous_version.6,4
+  </div>
+</Tooltip>
+`;
+
+exports[`should render correctly 1`] = `
+<Tooltip
+  overlay={
+    <div>
+      <DateFromNow
+        date={2017-05-16T11:50:02.000Z}
+      />
+      , 
+      <DateFormatter
+        date={2017-05-16T11:50:02.000Z}
+        long={true}
+      />
+    </div>
+  }
+>
+  <div
+    className="domain-measures-leak-header"
+  >
+    overview.new_code_period_x.overview.period.previous_version.6,4
+  </div>
+</Tooltip>
+`;
+
+exports[`should render correctly 2`] = `
+<div
+  className="domain-measures-leak-header"
+>
+  overview.new_code_period_x.overview.period.days.18
+</div>
+`;
+
+exports[`should render correctly for APP 1`] = `
+<div
+  className="domain-measures-leak-header"
+>
+  issues.new_code_period
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.js b/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.js
deleted file mode 100644 (file)
index de42924..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import DateFromNow from '../../../components/intl/DateFromNow';
-import DateFormatter from '../../../components/intl/DateFormatter';
-import Tooltip from '../../../components/controls/Tooltip';
-import { getPeriodDate, getPeriodLabel } from '../../../helpers/periods';
-import { translateWithParameters } from '../../../helpers/l10n';
-
-/*::
-type DaysPeriod = {
-  date: string,
-  mode: 'days',
-  parameter: string
-};
-*/
-
-/*::
-type DatePeriod = {
-  date: string,
-  mode: 'date',
-  parameter: string
-};
-*/
-
-/*::
-type VersionPeriod = {
-  date: string,
-  mode: 'version',
-  parameter: string
-};
-*/
-
-/*::
-type PreviousAnalysisPeriod = {
-  date: string,
-  mode: 'previous_analysis'
-};
-*/
-
-/*::
-type PreviousVersionPeriod = {
-  date: string,
-  mode: 'previous_version'
-};
-*/
-
-/*::
-type Period =
-  | DaysPeriod
-  | DatePeriod
-  | VersionPeriod
-  | PreviousAnalysisPeriod
-  | PreviousVersionPeriod; */
-
-export default function LeakPeriodLegend({ period } /*: { period: Period } */) {
-  const leakPeriodLabel = getPeriodLabel(period);
-
-  if (period.mode === 'days') {
-    return (
-      <div className="overview-legend overview-legend-spaced-line">
-        {translateWithParameters('overview.new_code_period_x', leakPeriodLabel)}
-      </div>
-    );
-  }
-
-  const leakPeriodDate = getPeriodDate(period);
-  const tooltip = (
-    <DateFormatter date={leakPeriodDate} long={true}>
-      {formattedLeakPeriodDate => (
-        <span>
-          {translateWithParameters(
-            ['date'].includes(period.mode)
-              ? 'overview.last_analysis_on_x'
-              : 'overview.started_on_x',
-            formattedLeakPeriodDate
-          )}
-        </span>
-      )}
-    </DateFormatter>
-  );
-  return (
-    <Tooltip overlay={tooltip}>
-      <div className="overview-legend">
-        {translateWithParameters('overview.new_code_period_x', leakPeriodLabel)}
-        <br />
-        <DateFromNow date={leakPeriodDate}>
-          {fromNow => (
-            <span className="note">
-              {translateWithParameters(
-                ['date'].includes(period.mode) ? 'overview.last_analysis_x' : 'overview.started_x',
-                fromNow
-              )}
-            </span>
-          )}
-        </DateFromNow>
-      </div>
-    </Tooltip>
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx b/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx
new file mode 100644 (file)
index 0000000..090aace
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as React from 'react';
+import DateFromNow from '../../../components/intl/DateFromNow';
+import DateFormatter from '../../../components/intl/DateFormatter';
+import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
+import Tooltip from '../../../components/controls/Tooltip';
+import { getPeriodDate, getPeriodLabel, Period, PeriodMode } from '../../../helpers/periods';
+import { translateWithParameters } from '../../../helpers/l10n';
+import { differenceInDays } from '../../../helpers/dates';
+
+interface Props {
+  period: Period;
+}
+
+export default function LeakPeriodLegend({ period }: Props) {
+  const leakPeriodLabel = getPeriodLabel(period);
+  if (!leakPeriodLabel) {
+    return null;
+  }
+
+  if (period.mode === PeriodMode.days) {
+    return (
+      <div className="overview-legend overview-legend-spaced-line">
+        {translateWithParameters('overview.new_code_period_x', leakPeriodLabel)}
+      </div>
+    );
+  }
+
+  const leakPeriodDate = getPeriodDate(period);
+  if (!leakPeriodDate) {
+    return null;
+  }
+
+  const formattedDateFunction = (formattedLeakPeriodDate: string) => (
+    <span>
+      {translateWithParameters(
+        period.mode === PeriodMode.previousAnalysis
+          ? 'overview.previous_analysis_on_x'
+          : 'overview.started_on_x',
+        formattedLeakPeriodDate
+      )}
+    </span>
+  );
+
+  const tooltip =
+    differenceInDays(new Date(), leakPeriodDate) < 1 ? (
+      <DateTimeFormatter date={leakPeriodDate}>{formattedDateFunction}</DateTimeFormatter>
+    ) : (
+      <DateFormatter date={leakPeriodDate} long={true}>
+        {formattedDateFunction}
+      </DateFormatter>
+    );
+
+  return (
+    <Tooltip overlay={tooltip}>
+      <div className="overview-legend">
+        {translateWithParameters('overview.new_code_period_x', leakPeriodLabel)}
+        <br />
+        <DateFromNow date={leakPeriodDate}>
+          {fromNow => (
+            <span className="note">
+              {translateWithParameters(
+                period.mode === PeriodMode.previousAnalysis
+                  ? 'overview.previous_analysis_x'
+                  : 'overview.started_x',
+                fromNow
+              )}
+            </span>
+          )}
+        </DateFromNow>
+      </div>
+    </Tooltip>
+  );
+}
index 63aed5899de3605d0d3092dd0fcda3a23031ea09..dc61e0ef7a8092fa8e058cbd5f99c7ca30070579 100644 (file)
@@ -160,7 +160,7 @@ export class OverviewApp extends React.PureComponent<Props, State> {
 
   getApplicationLeakPeriod = () =>
     this.state.measures.find(measure => measure.metric.key === 'new_bugs')
-      ? { index: 1 }
+      ? ({ index: 1 } as Period)
       : undefined;
 
   isEmpty = () =>
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.js b/server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.js
deleted file mode 100644 (file)
index 57ab92d..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 React from 'react';
-import { shallow } from 'enzyme';
-import LeakPeriodLegend from '../LeakPeriodLegend';
-
-describe('check note', () => {
-  it('10 days', () => {
-    const period = {
-      date: '2013-09-22T00:00:00+0200',
-      mode: 'days',
-      parameter: '10'
-    };
-    expect(shallow(<LeakPeriodLegend period={period} />)).toMatchSnapshot();
-  });
-
-  it('date', () => {
-    const period = {
-      date: '2013-09-22T00:00:00+0200',
-      mode: 'date',
-      parameter: '2013-01-01'
-    };
-    expect(shallow(<LeakPeriodLegend period={period} />).find('DateFromNow')).toMatchSnapshot();
-  });
-
-  it('version', () => {
-    const period = {
-      date: '2013-09-22T00:00:00+0200',
-      mode: 'version',
-      parameter: '0.1'
-    };
-    expect(shallow(<LeakPeriodLegend period={period} />).find('DateFromNow')).toMatchSnapshot();
-  });
-
-  it('previous_version', () => {
-    const period = {
-      date: '2013-09-22T00:00:00+0200',
-      mode: 'previous_version'
-    };
-    expect(shallow(<LeakPeriodLegend period={period} />).find('DateFromNow')).toHaveLength(1);
-  });
-
-  it('previous_analysis', () => {
-    const period = {
-      date: '2013-09-22T00:00:00+0200',
-      mode: 'previous_analysis'
-    };
-    expect(shallow(<LeakPeriodLegend period={period} />).find('DateFromNow')).toHaveLength(1);
-  });
-});
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.tsx b/server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.tsx
new file mode 100644 (file)
index 0000000..77d51c4
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as React from 'react';
+import { shallow } from 'enzyme';
+import LeakPeriodLegend from '../LeakPeriodLegend';
+import { PeriodMode } from '../../../../helpers/periods';
+import { differenceInDays } from '../../../../helpers/dates';
+
+jest.mock('../../../../helpers/dates', () => {
+  const dates = require.requireActual('../../../../helpers/dates');
+  dates.differenceInDays = jest.fn().mockReturnValue(10);
+  return dates;
+});
+
+it('10 days', () => {
+  const period = {
+    date: '2013-09-22T00:00:00+0200',
+    index: 0,
+    mode: PeriodMode.days,
+    parameter: '10'
+  };
+  expect(shallow(<LeakPeriodLegend period={period} />)).toMatchSnapshot();
+});
+
+it('date', () => {
+  const period = {
+    date: '2013-09-22T00:00:00+0200',
+    index: 0,
+    mode: PeriodMode.date,
+    parameter: '2013-01-01'
+  };
+  expect(shallow(<LeakPeriodLegend period={period} />)).toMatchSnapshot();
+});
+
+it('version', () => {
+  const period = {
+    date: '2013-09-22T00:00:00+0200',
+    index: 0,
+    mode: PeriodMode.version,
+    parameter: '0.1'
+  };
+  expect(shallow(<LeakPeriodLegend period={period} />).find('.overview-legend')).toMatchSnapshot();
+});
+
+it('previous_version', () => {
+  const period = {
+    date: '2013-09-22T00:00:00+0200',
+    index: 0,
+    mode: PeriodMode.previousVersion
+  };
+  expect(shallow(<LeakPeriodLegend period={period} />).find('.overview-legend')).toMatchSnapshot();
+});
+
+it('previous_analysis', () => {
+  const period = {
+    date: '2013-09-22T00:00:00+0200',
+    index: 0,
+    mode: PeriodMode.previousAnalysis
+  };
+  expect(shallow(<LeakPeriodLegend period={period} />).find('.overview-legend')).toMatchSnapshot();
+});
+
+it('should render a more precise date', () => {
+  (differenceInDays as jest.Mock<any>).mockReturnValueOnce(0);
+  const period = {
+    date: '2018-08-17T00:00:00+0200',
+    index: 0,
+    mode: PeriodMode.previousVersion
+  };
+  expect(shallow(<LeakPeriodLegend period={period} />)).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/LeakPeriodLegend-test.js.snap b/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/LeakPeriodLegend-test.js.snap
deleted file mode 100644 (file)
index afbce5c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`check note 10 days 1`] = `
-<div
-  className="overview-legend overview-legend-spaced-line"
->
-  overview.new_code_period_x.overview.period.days.10
-</div>
-`;
-
-exports[`check note date 1`] = `
-<DateFromNow
-  date={2013-09-21T22:00:00.000Z}
-/>
-`;
-
-exports[`check note version 1`] = `
-<DateFromNow
-  date={2013-09-21T22:00:00.000Z}
-/>
-`;
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/LeakPeriodLegend-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/LeakPeriodLegend-test.tsx.snap
new file mode 100644 (file)
index 0000000..981c88b
--- /dev/null
@@ -0,0 +1,90 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`10 days 1`] = `
+<div
+  className="overview-legend overview-legend-spaced-line"
+>
+  overview.new_code_period_x.overview.period.days.10
+</div>
+`;
+
+exports[`date 1`] = `
+<Tooltip
+  overlay={
+    <DateFormatter
+      date={2013-09-21T22:00:00.000Z}
+      long={true}
+    >
+      [Function]
+    </DateFormatter>
+  }
+>
+  <div
+    className="overview-legend"
+  >
+    overview.new_code_period_x.overview.period.date.2013-01-01
+    <br />
+    <DateFromNow
+      date={2013-09-21T22:00:00.000Z}
+    />
+  </div>
+</Tooltip>
+`;
+
+exports[`previous_analysis 1`] = `
+<div
+  className="overview-legend"
+>
+  overview.new_code_period_x.overview.period.previous_analysis.
+  <br />
+  <DateFromNow
+    date={2013-09-21T22:00:00.000Z}
+  />
+</div>
+`;
+
+exports[`previous_version 1`] = `
+<div
+  className="overview-legend"
+>
+  overview.new_code_period_x.overview.period.previous_version_only_date
+  <br />
+  <DateFromNow
+    date={2013-09-21T22:00:00.000Z}
+  />
+</div>
+`;
+
+exports[`should render a more precise date 1`] = `
+<Tooltip
+  overlay={
+    <DateTimeFormatter
+      date={2018-08-16T22:00:00.000Z}
+    >
+      [Function]
+    </DateTimeFormatter>
+  }
+>
+  <div
+    className="overview-legend"
+  >
+    overview.new_code_period_x.overview.period.previous_version_only_date
+    <br />
+    <DateFromNow
+      date={2018-08-16T22:00:00.000Z}
+    />
+  </div>
+</Tooltip>
+`;
+
+exports[`version 1`] = `
+<div
+  className="overview-legend"
+>
+  overview.new_code_period_x.overview.period.version.0.1
+  <br />
+  <DateFromNow
+    date={2013-09-21T22:00:00.000Z}
+  />
+</div>
+`;
index b5509cbd7383fa2464c519bf14b4158a3a991604..44aecab78af59826558ee22182aa8ddb263037d1 100644 (file)
@@ -33,7 +33,7 @@ import {
   getRatingTooltip
 } from '../../../helpers/measures';
 import { getLocalizedMetricName } from '../../../helpers/l10n';
-import { getPeriodDate } from '../../../helpers/periods';
+import { getPeriodDate, Period } from '../../../helpers/periods';
 import {
   getComponentDrilldownUrl,
   getComponentIssuesUrl,
@@ -47,7 +47,7 @@ export interface EnhanceProps {
   branchLike?: BranchLike;
   component: Component;
   measures: MeasureEnhanced[];
-  leakPeriod?: { index: number; date?: string };
+  leakPeriod?: Period;
   history?: History;
   historyStartDate?: Date;
 }
index afc0edf1c49c12422aacdd42aeeb9df0a543a85d..7583847872999b23134e7d062dc0a65095eee7e4 100644 (file)
 import { translate, translateWithParameters } from './l10n';
 import { parseDate } from './dates';
 
+export enum PeriodMode {
+  days = 'days',
+  date = 'date',
+  version = 'version',
+  previousAnalysis = 'previous_analysis',
+  previousVersion = 'previous_version'
+}
+
 export interface Period {
   date: string;
   index: number;
-  mode: string;
+  mode: PeriodMode;
   modeParam?: string;
-  parameter: string;
+  parameter?: string;
 }
 
-export function getPeriod(periods: Period[] | undefined, index: number): Period | undefined {
+export function getPeriod(periods: Period[] | undefined, index: number) {
   if (!Array.isArray(periods)) {
     return undefined;
   }
@@ -36,22 +44,21 @@ export function getPeriod(periods: Period[] | undefined, index: number): Period
   return periods.find(period => period.index === index);
 }
 
-export function getLeakPeriod(periods: Period[] | undefined): Period | undefined {
+export function getLeakPeriod(periods: Period[] | undefined) {
   return getPeriod(periods, 1);
 }
 
-export function getPeriodLabel(period: Period | undefined): string | undefined {
+export function getPeriodLabel(period: Period | undefined) {
   if (!period) {
     return undefined;
   }
 
   const parameter = period.modeParam || period.parameter;
-
   if (period.mode === 'previous_version' && !parameter) {
     return translate('overview.period.previous_version_only_date');
   }
 
-  return translateWithParameters(`overview.period.${period.mode}`, parameter);
+  return translateWithParameters(`overview.period.${period.mode}`, parameter || '');
 }
 
 export function getPeriodDate(period?: { date?: string }): Date | undefined {
index e9dd6677ef6d7cfd6c27b8f5e1ff6ea172c0c1bf..796b4439143cd1bf5bde86b86598e5e2e3e659bc 100644 (file)
@@ -898,7 +898,7 @@ property.error.notFloat=Not a floating point number
 property.error.notRegexp=Not a valid Java regular expression
 property.error.notInOptions=Not a valid option
 property.category.scm=SCM
-property.sonar.leak.period.description=Period used to compare measures and track new issues. Values are:<ul class='bullet'><li>Number of days before  analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, for example 2010-12-25</li><li>'previous_version' to compare to the previous version in the project history</li><li>A version, for example '1.2' or 'BASELINE'</li></ul><p>When specifying a number of days or a date, the snapshot selected for comparison is the first one available inside the corresponding time range. </p><p>Changing this property only takes effect after subsequent project inspections.<p/>
+property.sonar.leak.period.description=Period used to compare measures and track new issues. Values are:<ul class='bullet'><li>Number of days before  analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, for example 2010-12-25</li><li>'previous_version' to compare to the previous version in the project history</li><li>A version, for example '1.2' or 'BASELINE'</li></ul><p>When specifying a number of days or a date, the snapshot selected as the baseline for comparison is the first one available inside the corresponding time range. Specifically, the first analysis in the range is considered to be before the leak period(/new code period). </p><p>Changing this property only takes effect after subsequent project inspections.<p/>
 property.sonar.branch.longLivedBranches.regex.description=Regular expression used to detect whether a branch is a long living branch (as opposed to short living branch), based on its name. This applies only during first analysis, the type of a branch cannot be changed later.
 
 
@@ -2357,9 +2357,9 @@ overview.quality_gate.ignored_conditions.tooltip=At the start of a new code peri
 overview.quality_profiles=Quality Profiles
 overview.new_code_period_x=New code: {0}
 overview.started_x=started {0}
-overview.last_analysis_x=last analysis {0}
+overview.previous_analysis_x=Previous analysis {0}
 overview.started_on_x=Started on {0}
-overview.last_analysis_on_x=Last analysis on {0}
+overview.previous_analysis_on_x=Previous analysis on {0}
 overview.on_new_code=On New Code
 overview.about_this_portfolio=About This Portfolio
 overview.about_this_project.APP=About This Application
@@ -2407,7 +2407,7 @@ overview.period.previous_version_only_date=since previous version
 overview.period.previous_analysis=since previous analysis
 overview.period.days=last {0} days
 overview.period.version=since {0}
-overview.period.date=since {0}
+overview.period.date=after {0}
 
 overview.gate.ERROR=Failed
 overview.gate.WARN=Warning