diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2018-10-25 13:28:11 +0000 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2018-10-25 13:28:11 +0000 |
commit | 86d8fd86a719aa493905d7168d6f9da433ad8600 (patch) | |
tree | cf4af59956f82099b6ebb8def822da3c39125c31 | |
parent | 719f46e2959354c51cba9e61b86d88c6b2006962 (diff) | |
parent | c26d95311b487e9a696f97f89b180c28f5094d3d (diff) | |
download | gitlab-ce-86d8fd86a719aa493905d7168d6f9da433ad8600.tar.gz |
Merge branch '53055-combine-date-util-functions' into 'master'
Combine all datetime library functions into `datetime_utility.js`
This MR moves datetime methods from `app/assets/javascripts/lib/utils/pretty_time.js` & `app/assets/javascripts/lib/utils/datefix.js` into `app/assets/javascripts/lib/utils/datetime_utility.js`.
Closes #53055
See merge request gitlab-org/gitlab-ce!22570
-rw-r--r-- | app/assets/javascripts/due_date_select.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/issuable_form.js | 34 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/datefix.js | 28 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/datetime_utility.js | 106 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/pretty_time.js | 63 | ||||
-rw-r--r-- | app/assets/javascripts/member_expiration_date.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue | 192 | ||||
-rw-r--r-- | app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue | 2 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/pikaday.vue | 2 | ||||
-rw-r--r-- | changelogs/unreleased/53055-combine-date-util-functions.yml | 5 | ||||
-rw-r--r-- | spec/javascripts/datetime_utility_spec.js | 160 | ||||
-rw-r--r-- | spec/javascripts/lib/utils/datefix_spec.js | 27 | ||||
-rw-r--r-- | spec/javascripts/pretty_time_spec.js | 135 |
13 files changed, 379 insertions, 380 deletions
diff --git a/app/assets/javascripts/due_date_select.js b/app/assets/javascripts/due_date_select.js index c7b5a35cc14..dbfcf8cc921 100644 --- a/app/assets/javascripts/due_date_select.js +++ b/app/assets/javascripts/due_date_select.js @@ -3,8 +3,7 @@ import Pikaday from 'pikaday'; import dateFormat from 'dateformat'; import { __ } from '~/locale'; import axios from './lib/utils/axios_utils'; -import { timeFor } from './lib/utils/datetime_utility'; -import { parsePikadayDate, pikadayToString } from './lib/utils/datefix'; +import { timeFor, parsePikadayDate, pikadayToString } from './lib/utils/datetime_utility'; import boardsStore from './boards/stores/boards_store'; class DueDateSelect { diff --git a/app/assets/javascripts/issuable_form.js b/app/assets/javascripts/issuable_form.js index 0140960b367..c81a2230310 100644 --- a/app/assets/javascripts/issuable_form.js +++ b/app/assets/javascripts/issuable_form.js @@ -1,6 +1,3 @@ -/* eslint-disable no-new, no-unused-vars, consistent-return, no-else-return */ -/* global GitLab */ - import $ from 'jquery'; import Pikaday from 'pikaday'; import Autosave from './autosave'; @@ -8,7 +5,7 @@ import UsersSelect from './users_select'; import GfmAutoComplete from './gfm_auto_complete'; import ZenMode from './zen_mode'; import AutoWidthDropdownSelect from './issuable/auto_width_dropdown_select'; -import { parsePikadayDate, pikadayToString } from './lib/utils/datefix'; +import { parsePikadayDate, pikadayToString } from './lib/utils/datetime_utility'; export default class IssuableForm { constructor(form) { @@ -19,9 +16,11 @@ export default class IssuableForm { this.handleSubmit = this.handleSubmit.bind(this); this.wipRegex = /^\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i; - new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources).setup(); - new UsersSelect(); - new ZenMode(); + this.gfmAutoComplete = new GfmAutoComplete( + gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources, + ).setup(); + this.usersSelect = new UsersSelect(); + this.zenMode = new ZenMode(); this.titleField = this.form.find('input[name*="[title]"]'); this.descriptionField = this.form.find('textarea[name*="[description]"]'); @@ -57,8 +56,16 @@ export default class IssuableForm { } initAutosave() { - new Autosave(this.titleField, [document.location.pathname, document.location.search, 'title']); - return new Autosave(this.descriptionField, [document.location.pathname, document.location.search, 'description']); + this.autosave = new Autosave(this.titleField, [ + document.location.pathname, + document.location.search, + 'title', + ]); + return new Autosave(this.descriptionField, [ + document.location.pathname, + document.location.search, + 'description', + ]); } handleSubmit() { @@ -74,7 +81,7 @@ export default class IssuableForm { this.$wipExplanation = this.form.find('.js-wip-explanation'); this.$noWipExplanation = this.form.find('.js-no-wip-explanation'); if (!(this.$wipExplanation.length && this.$noWipExplanation.length)) { - return; + return undefined; } this.form.on('click', '.js-toggle-wip', this.toggleWip); this.titleField.on('keyup blur', this.renderWipExplanation); @@ -89,10 +96,9 @@ export default class IssuableForm { if (this.workInProgress()) { this.$wipExplanation.show(); return this.$noWipExplanation.hide(); - } else { - this.$wipExplanation.hide(); - return this.$noWipExplanation.show(); } + this.$wipExplanation.hide(); + return this.$noWipExplanation.show(); } toggleWip(event) { @@ -110,7 +116,7 @@ export default class IssuableForm { } addWip() { - this.titleField.val(`WIP: ${(this.titleField.val())}`); + this.titleField.val(`WIP: ${this.titleField.val()}`); } initTargetBranchDropdown() { diff --git a/app/assets/javascripts/lib/utils/datefix.js b/app/assets/javascripts/lib/utils/datefix.js deleted file mode 100644 index 19e4085dbbb..00000000000 --- a/app/assets/javascripts/lib/utils/datefix.js +++ /dev/null @@ -1,28 +0,0 @@ -export const pad = (val, len = 2) => `0${val}`.slice(-len); - -/** - * Formats dates in Pickaday - * @param {String} dateString Date in yyyy-mm-dd format - * @return {Date} UTC format - */ -export const parsePikadayDate = dateString => { - const parts = dateString.split('-'); - const year = parseInt(parts[0], 10); - const month = parseInt(parts[1] - 1, 10); - const day = parseInt(parts[2], 10); - - return new Date(year, month, day); -}; - -/** - * Used `onSelect` method in pickaday - * @param {Date} date UTC format - * @return {String} Date formated in yyyy-mm-dd - */ -export const pikadayToString = date => { - const day = pad(date.getDate()); - const month = pad(date.getMonth() + 1); - const year = date.getFullYear(); - - return `${year}-${month}-${day}`; -}; diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index 833dbefd3dc..1bdf98d0c97 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -1,4 +1,5 @@ import $ from 'jquery'; +import _ from 'underscore'; import timeago from 'timeago.js'; import dateFormat from 'dateformat'; import { pluralize } from './text_utility'; @@ -46,6 +47,8 @@ const getMonthNames = abbreviated => { ]; }; +export const pad = (val, len = 2) => `0${val}`.slice(-len); + /** * Given a date object returns the day of the week in English * @param {date} date @@ -74,10 +77,10 @@ let timeagoInstance; /** * Sets a timeago Instance */ -export function getTimeago() { +export const getTimeago = () => { if (!timeagoInstance) { - const localeRemaining = function getLocaleRemaining(number, index) { - return [ + const localeRemaining = (number, index) => + [ [s__('Timeago|just now'), s__('Timeago|right now')], [s__('Timeago|%s seconds ago'), s__('Timeago|%s seconds remaining')], [s__('Timeago|1 minute ago'), s__('Timeago|1 minute remaining')], @@ -93,9 +96,9 @@ export function getTimeago() { [s__('Timeago|1 year ago'), s__('Timeago|1 year remaining')], [s__('Timeago|%s years ago'), s__('Timeago|%s years remaining')], ][index]; - }; - const locale = function getLocale(number, index) { - return [ + + const locale = (number, index) => + [ [s__('Timeago|just now'), s__('Timeago|right now')], [s__('Timeago|%s seconds ago'), s__('Timeago|in %s seconds')], [s__('Timeago|1 minute ago'), s__('Timeago|in 1 minute')], @@ -111,7 +114,6 @@ export function getTimeago() { [s__('Timeago|1 year ago'), s__('Timeago|in 1 year')], [s__('Timeago|%s years ago'), s__('Timeago|in %s years')], ][index]; - }; timeago.register(timeagoLanguageCode, locale); timeago.register(`${timeagoLanguageCode}-remaining`, localeRemaining); @@ -119,7 +121,7 @@ export function getTimeago() { } return timeagoInstance; -} +}; /** * For the given element, renders a timeago instance. @@ -184,7 +186,7 @@ export const getDayDifference = (a, b) => { * @param {Number} seconds * @return {String} */ -export function timeIntervalInWords(intervalInSeconds) { +export const timeIntervalInWords = intervalInSeconds => { const secondsInteger = parseInt(intervalInSeconds, 10); const minutes = Math.floor(secondsInteger / 60); const seconds = secondsInteger - minutes * 60; @@ -196,9 +198,9 @@ export function timeIntervalInWords(intervalInSeconds) { text = `${seconds} ${pluralize('second', seconds)}`; } return text; -} +}; -export function dateInWords(date, abbreviated = false, hideYear = false) { +export const dateInWords = (date, abbreviated = false, hideYear = false) => { if (!date) return date; const month = date.getMonth(); @@ -240,7 +242,7 @@ export function dateInWords(date, abbreviated = false, hideYear = false) { } return `${monthName} ${date.getDate()}, ${year}`; -} +}; /** * Returns month name based on provided date. @@ -391,3 +393,83 @@ export const formatTime = milliseconds => { formattedTime += remainingSeconds; return formattedTime; }; + +/** + * Formats dates in Pickaday + * @param {String} dateString Date in yyyy-mm-dd format + * @return {Date} UTC format + */ +export const parsePikadayDate = dateString => { + const parts = dateString.split('-'); + const year = parseInt(parts[0], 10); + const month = parseInt(parts[1] - 1, 10); + const day = parseInt(parts[2], 10); + + return new Date(year, month, day); +}; + +/** + * Used `onSelect` method in pickaday + * @param {Date} date UTC format + * @return {String} Date formated in yyyy-mm-dd + */ +export const pikadayToString = date => { + const day = pad(date.getDate()); + const month = pad(date.getMonth() + 1); + const year = date.getFullYear(); + + return `${year}-${month}-${day}`; +}; + +/** + * Accepts seconds and returns a timeObject { weeks: #, days: #, hours: #, minutes: # } + * Seconds can be negative or positive, zero or non-zero. Can be configured for any day + * or week length. + */ +export const parseSeconds = (seconds, { daysPerWeek = 5, hoursPerDay = 8 } = {}) => { + const DAYS_PER_WEEK = daysPerWeek; + const HOURS_PER_DAY = hoursPerDay; + const MINUTES_PER_HOUR = 60; + const MINUTES_PER_WEEK = DAYS_PER_WEEK * HOURS_PER_DAY * MINUTES_PER_HOUR; + const MINUTES_PER_DAY = HOURS_PER_DAY * MINUTES_PER_HOUR; + + const timePeriodConstraints = { + weeks: MINUTES_PER_WEEK, + days: MINUTES_PER_DAY, + hours: MINUTES_PER_HOUR, + minutes: 1, + }; + + let unorderedMinutes = Math.abs(seconds / MINUTES_PER_HOUR); + + return _.mapObject(timePeriodConstraints, minutesPerPeriod => { + const periodCount = Math.floor(unorderedMinutes / minutesPerPeriod); + + unorderedMinutes -= periodCount * minutesPerPeriod; + + return periodCount; + }); +}; + +/** + * Accepts a timeObject (see parseSeconds) and returns a condensed string representation of it + * (e.g. '1w 2d 3h 1m' or '1h 30m'). Zero value units are not included. + */ +export const stringifyTime = timeObject => { + const reducedTime = _.reduce( + timeObject, + (memo, unitValue, unitName) => { + const isNonZero = !!unitValue; + return isNonZero ? `${memo} ${unitValue}${unitName.charAt(0)}` : memo; + }, + '', + ).trim(); + return reducedTime.length ? reducedTime : '0m'; +}; + +/** + * Accepts a time string of any size (e.g. '1w 2d 3h 5m' or '1w 2d') and returns + * the first non-zero unit/value pair. + */ +export const abbreviateTime = timeStr => + timeStr.split(' ').filter(unitStr => unitStr.charAt(0) !== '0')[0]; diff --git a/app/assets/javascripts/lib/utils/pretty_time.js b/app/assets/javascripts/lib/utils/pretty_time.js deleted file mode 100644 index d92b8a7179f..00000000000 --- a/app/assets/javascripts/lib/utils/pretty_time.js +++ /dev/null @@ -1,63 +0,0 @@ -import _ from 'underscore'; - -/* - * TODO: Make these methods more configurable (e.g. stringifyTime condensed or - * non-condensed, abbreviateTimelengths) - * */ - -/* - * Accepts seconds and returns a timeObject { weeks: #, days: #, hours: #, minutes: # } - * Seconds can be negative or positive, zero or non-zero. Can be configured for any day - * or week length. -*/ - -export function parseSeconds(seconds, { daysPerWeek = 5, hoursPerDay = 8 } = {}) { - const DAYS_PER_WEEK = daysPerWeek; - const HOURS_PER_DAY = hoursPerDay; - const MINUTES_PER_HOUR = 60; - const MINUTES_PER_WEEK = DAYS_PER_WEEK * HOURS_PER_DAY * MINUTES_PER_HOUR; - const MINUTES_PER_DAY = HOURS_PER_DAY * MINUTES_PER_HOUR; - - const timePeriodConstraints = { - weeks: MINUTES_PER_WEEK, - days: MINUTES_PER_DAY, - hours: MINUTES_PER_HOUR, - minutes: 1, - }; - - let unorderedMinutes = Math.abs(seconds / MINUTES_PER_HOUR); - - return _.mapObject(timePeriodConstraints, minutesPerPeriod => { - const periodCount = Math.floor(unorderedMinutes / minutesPerPeriod); - - unorderedMinutes -= periodCount * minutesPerPeriod; - - return periodCount; - }); -} - -/* -* Accepts a timeObject (see parseSeconds) and returns a condensed string representation of it -* (e.g. '1w 2d 3h 1m' or '1h 30m'). Zero value units are not included. -*/ - -export function stringifyTime(timeObject) { - const reducedTime = _.reduce( - timeObject, - (memo, unitValue, unitName) => { - const isNonZero = !!unitValue; - return isNonZero ? `${memo} ${unitValue}${unitName.charAt(0)}` : memo; - }, - '', - ).trim(); - return reducedTime.length ? reducedTime : '0m'; -} - -/* -* Accepts a time string of any size (e.g. '1w 2d 3h 5m' or '1w 2d') and returns -* the first non-zero unit/value pair. -*/ - -export function abbreviateTime(timeStr) { - return timeStr.split(' ').filter(unitStr => unitStr.charAt(0) !== '0')[0]; -} diff --git a/app/assets/javascripts/member_expiration_date.js b/app/assets/javascripts/member_expiration_date.js index df5cd1b8c51..0beedcacf33 100644 --- a/app/assets/javascripts/member_expiration_date.js +++ b/app/assets/javascripts/member_expiration_date.js @@ -1,6 +1,6 @@ import $ from 'jquery'; import Pikaday from 'pikaday'; -import { parsePikadayDate, pikadayToString } from './lib/utils/datefix'; +import { parsePikadayDate, pikadayToString } from './lib/utils/datetime_utility'; // Add datepickers to all `js-access-expiration-date` elements. If those elements are // children of an element with the `clearable-input` class, and have a sibling diff --git a/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue b/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue index 1d030c4f67f..259858e4b46 100644 --- a/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue +++ b/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue @@ -1,111 +1,111 @@ <script> - import { __, sprintf } from '~/locale'; - import { abbreviateTime } from '~/lib/utils/pretty_time'; - import icon from '~/vue_shared/components/icon.vue'; - import tooltip from '~/vue_shared/directives/tooltip'; +import { __, sprintf } from '~/locale'; +import { abbreviateTime } from '~/lib/utils/datetime_utility'; +import icon from '~/vue_shared/components/icon.vue'; +import tooltip from '~/vue_shared/directives/tooltip'; - export default { - name: 'TimeTrackingCollapsedState', - components: { - icon, +export default { + name: 'TimeTrackingCollapsedState', + components: { + icon, + }, + directives: { + tooltip, + }, + props: { + showComparisonState: { + type: Boolean, + required: true, }, - directives: { - tooltip, + showSpentOnlyState: { + type: Boolean, + required: true, }, - props: { - showComparisonState: { - type: Boolean, - required: true, - }, - showSpentOnlyState: { - type: Boolean, - required: true, - }, - showEstimateOnlyState: { - type: Boolean, - required: true, - }, - showNoTimeTrackingState: { - type: Boolean, - required: true, - }, - timeSpentHumanReadable: { - type: String, - required: false, - default: '', - }, - timeEstimateHumanReadable: { - type: String, - required: false, - default: '', - }, + showEstimateOnlyState: { + type: Boolean, + required: true, }, - computed: { - timeSpent() { - return this.abbreviateTime(this.timeSpentHumanReadable); - }, - timeEstimate() { - return this.abbreviateTime(this.timeEstimateHumanReadable); - }, - divClass() { - if (this.showComparisonState) { - return 'compare'; - } else if (this.showEstimateOnlyState) { - return 'estimate-only'; - } else if (this.showSpentOnlyState) { - return 'spend-only'; - } else if (this.showNoTimeTrackingState) { - return 'no-tracking'; - } + showNoTimeTrackingState: { + type: Boolean, + required: true, + }, + timeSpentHumanReadable: { + type: String, + required: false, + default: '', + }, + timeEstimateHumanReadable: { + type: String, + required: false, + default: '', + }, + }, + computed: { + timeSpent() { + return this.abbreviateTime(this.timeSpentHumanReadable); + }, + timeEstimate() { + return this.abbreviateTime(this.timeEstimateHumanReadable); + }, + divClass() { + if (this.showComparisonState) { + return 'compare'; + } else if (this.showEstimateOnlyState) { + return 'estimate-only'; + } else if (this.showSpentOnlyState) { + return 'spend-only'; + } else if (this.showNoTimeTrackingState) { + return 'no-tracking'; + } + return ''; + }, + spanClass() { + if (this.showComparisonState) { return ''; - }, - spanClass() { - if (this.showComparisonState) { - return ''; - } else if (this.showEstimateOnlyState || this.showSpentOnlyState) { - return 'bold'; - } else if (this.showNoTimeTrackingState) { - return 'no-value'; - } + } else if (this.showEstimateOnlyState || this.showSpentOnlyState) { + return 'bold'; + } else if (this.showNoTimeTrackingState) { + return 'no-value'; + } - return ''; - }, - text() { - if (this.showComparisonState) { - return `${this.timeSpent} / ${this.timeEstimate}`; - } else if (this.showEstimateOnlyState) { - return `-- / ${this.timeEstimate}`; - } else if (this.showSpentOnlyState) { - return `${this.timeSpent} / --`; - } else if (this.showNoTimeTrackingState) { - return 'None'; - } + return ''; + }, + text() { + if (this.showComparisonState) { + return `${this.timeSpent} / ${this.timeEstimate}`; + } else if (this.showEstimateOnlyState) { + return `-- / ${this.timeEstimate}`; + } else if (this.showSpentOnlyState) { + return `${this.timeSpent} / --`; + } else if (this.showNoTimeTrackingState) { + return 'None'; + } - return ''; - }, - timeTrackedTooltipText() { - let title; - if (this.showComparisonState) { - title = __('Time remaining'); - } else if (this.showEstimateOnlyState) { - title = __('Estimated'); - } else if (this.showSpentOnlyState) { - title = __('Time spent'); - } + return ''; + }, + timeTrackedTooltipText() { + let title; + if (this.showComparisonState) { + title = __('Time remaining'); + } else if (this.showEstimateOnlyState) { + title = __('Estimated'); + } else if (this.showSpentOnlyState) { + title = __('Time spent'); + } - return sprintf('%{title}: %{text}', ({ title, text: this.text })); - }, - tooltipText() { - return this.showNoTimeTrackingState ? __('Time tracking') : this.timeTrackedTooltipText; - }, + return sprintf('%{title}: %{text}', { title, text: this.text }); + }, + tooltipText() { + return this.showNoTimeTrackingState ? __('Time tracking') : this.timeTrackedTooltipText; }, - methods: { - abbreviateTime(timeStr) { - return abbreviateTime(timeStr); - }, + }, + methods: { + abbreviateTime(timeStr) { + return abbreviateTime(timeStr); }, - }; + }, +}; </script> <template> diff --git a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue index dc599e1b9fc..e74912d628f 100644 --- a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue +++ b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue @@ -1,5 +1,5 @@ <script> -import { parseSeconds, stringifyTime } from '../../../lib/utils/pretty_time'; +import { parseSeconds, stringifyTime } from '~/lib/utils/datetime_utility'; import tooltip from '../../../vue_shared/directives/tooltip'; export default { diff --git a/app/assets/javascripts/vue_shared/components/pikaday.vue b/app/assets/javascripts/vue_shared/components/pikaday.vue index 782d8e3abf6..26c99aecae4 100644 --- a/app/assets/javascripts/vue_shared/components/pikaday.vue +++ b/app/assets/javascripts/vue_shared/components/pikaday.vue @@ -1,6 +1,6 @@ <script> import Pikaday from 'pikaday'; -import { parsePikadayDate, pikadayToString } from '../../lib/utils/datefix'; +import { parsePikadayDate, pikadayToString } from '~/lib/utils/datetime_utility'; export default { name: 'DatePicker', diff --git a/changelogs/unreleased/53055-combine-date-util-functions.yml b/changelogs/unreleased/53055-combine-date-util-functions.yml new file mode 100644 index 00000000000..56d4406f1bf --- /dev/null +++ b/changelogs/unreleased/53055-combine-date-util-functions.yml @@ -0,0 +1,5 @@ +--- +title: Combine all datetime library functions into 'datetime_utility.js' +merge_request: 22570 +author: +type: other diff --git a/spec/javascripts/datetime_utility_spec.js b/spec/javascripts/datetime_utility_spec.js index 9fedbcc4c25..2821f4d6793 100644 --- a/spec/javascripts/datetime_utility_spec.js +++ b/spec/javascripts/datetime_utility_spec.js @@ -192,3 +192,163 @@ describe('formatTime', () => { }); }); }); + +describe('datefix', () => { + describe('pad', () => { + it('should add a 0 when length is smaller than 2', () => { + expect(datetimeUtility.pad(2)).toEqual('02'); + }); + + it('should not add a zero when lenght matches the default', () => { + expect(datetimeUtility.pad(12)).toEqual('12'); + }); + + it('should add a 0 when lenght is smaller than the provided', () => { + expect(datetimeUtility.pad(12, 3)).toEqual('012'); + }); + }); + + describe('parsePikadayDate', () => { + // removed because of https://gitlab.com/gitlab-org/gitlab-ce/issues/39834 + }); + + describe('pikadayToString', () => { + it('should format a UTC date into yyyy-mm-dd format', () => { + expect(datetimeUtility.pikadayToString(new Date('2020-01-29:00:00'))).toEqual('2020-01-29'); + }); + }); +}); + +describe('prettyTime methods', () => { + const assertTimeUnits = (obj, minutes, hours, days, weeks) => { + expect(obj.minutes).toBe(minutes); + expect(obj.hours).toBe(hours); + expect(obj.days).toBe(days); + expect(obj.weeks).toBe(weeks); + }; + + describe('parseSeconds', () => { + it('should correctly parse a negative value', () => { + const zeroSeconds = datetimeUtility.parseSeconds(-1000); + + assertTimeUnits(zeroSeconds, 16, 0, 0, 0); + }); + + it('should correctly parse a zero value', () => { + const zeroSeconds = datetimeUtility.parseSeconds(0); + + assertTimeUnits(zeroSeconds, 0, 0, 0, 0); + }); + + it('should correctly parse a small non-zero second values', () => { + const subOneMinute = datetimeUtility.parseSeconds(10); + const aboveOneMinute = datetimeUtility.parseSeconds(100); + const manyMinutes = datetimeUtility.parseSeconds(1000); + + assertTimeUnits(subOneMinute, 0, 0, 0, 0); + assertTimeUnits(aboveOneMinute, 1, 0, 0, 0); + assertTimeUnits(manyMinutes, 16, 0, 0, 0); + }); + + it('should correctly parse large second values', () => { + const aboveOneHour = datetimeUtility.parseSeconds(4800); + const aboveOneDay = datetimeUtility.parseSeconds(110000); + const aboveOneWeek = datetimeUtility.parseSeconds(25000000); + + assertTimeUnits(aboveOneHour, 20, 1, 0, 0); + assertTimeUnits(aboveOneDay, 33, 6, 3, 0); + assertTimeUnits(aboveOneWeek, 26, 0, 3, 173); + }); + + it('should correctly accept a custom param for hoursPerDay', () => { + const config = { hoursPerDay: 24 }; + + const aboveOneHour = datetimeUtility.parseSeconds(4800, config); + const aboveOneDay = datetimeUtility.parseSeconds(110000, config); + const aboveOneWeek = datetimeUtility.parseSeconds(25000000, config); + + assertTimeUnits(aboveOneHour, 20, 1, 0, 0); + assertTimeUnits(aboveOneDay, 33, 6, 1, 0); + assertTimeUnits(aboveOneWeek, 26, 8, 4, 57); + }); + + it('should correctly accept a custom param for daysPerWeek', () => { + const config = { daysPerWeek: 7 }; + + const aboveOneHour = datetimeUtility.parseSeconds(4800, config); + const aboveOneDay = datetimeUtility.parseSeconds(110000, config); + const aboveOneWeek = datetimeUtility.parseSeconds(25000000, config); + + assertTimeUnits(aboveOneHour, 20, 1, 0, 0); + assertTimeUnits(aboveOneDay, 33, 6, 3, 0); + assertTimeUnits(aboveOneWeek, 26, 0, 0, 124); + }); + + it('should correctly accept custom params for daysPerWeek and hoursPerDay', () => { + const config = { daysPerWeek: 55, hoursPerDay: 14 }; + + const aboveOneHour = datetimeUtility.parseSeconds(4800, config); + const aboveOneDay = datetimeUtility.parseSeconds(110000, config); + const aboveOneWeek = datetimeUtility.parseSeconds(25000000, config); + + assertTimeUnits(aboveOneHour, 20, 1, 0, 0); + assertTimeUnits(aboveOneDay, 33, 2, 2, 0); + assertTimeUnits(aboveOneWeek, 26, 0, 1, 9); + }); + }); + + describe('stringifyTime', () => { + it('should stringify values with all non-zero units', () => { + const timeObject = { + weeks: 1, + days: 4, + hours: 7, + minutes: 20, + }; + + const timeString = datetimeUtility.stringifyTime(timeObject); + + expect(timeString).toBe('1w 4d 7h 20m'); + }); + + it('should stringify values with some non-zero units', () => { + const timeObject = { + weeks: 0, + days: 4, + hours: 0, + minutes: 20, + }; + + const timeString = datetimeUtility.stringifyTime(timeObject); + + expect(timeString).toBe('4d 20m'); + }); + + it('should stringify values with no non-zero units', () => { + const timeObject = { + weeks: 0, + days: 0, + hours: 0, + minutes: 0, + }; + + const timeString = datetimeUtility.stringifyTime(timeObject); + + expect(timeString).toBe('0m'); + }); + }); + + describe('abbreviateTime', () => { + it('should abbreviate stringified times for weeks', () => { + const fullTimeString = '1w 3d 4h 5m'; + + expect(datetimeUtility.abbreviateTime(fullTimeString)).toBe('1w'); + }); + + it('should abbreviate stringified times for non-weeks', () => { + const fullTimeString = '0w 3d 4h 5m'; + + expect(datetimeUtility.abbreviateTime(fullTimeString)).toBe('3d'); + }); + }); +}); diff --git a/spec/javascripts/lib/utils/datefix_spec.js b/spec/javascripts/lib/utils/datefix_spec.js deleted file mode 100644 index a9f3abcf2a4..00000000000 --- a/spec/javascripts/lib/utils/datefix_spec.js +++ /dev/null @@ -1,27 +0,0 @@ -import { pad, pikadayToString } from '~/lib/utils/datefix'; - -describe('datefix', () => { - describe('pad', () => { - it('should add a 0 when length is smaller than 2', () => { - expect(pad(2)).toEqual('02'); - }); - - it('should not add a zero when lenght matches the default', () => { - expect(pad(12)).toEqual('12'); - }); - - it('should add a 0 when lenght is smaller than the provided', () => { - expect(pad(12, 3)).toEqual('012'); - }); - }); - - describe('parsePikadayDate', () => { - // removed because of https://gitlab.com/gitlab-org/gitlab-ce/issues/39834 - }); - - describe('pikadayToString', () => { - it('should format a UTC date into yyyy-mm-dd format', () => { - expect(pikadayToString(new Date('2020-01-29:00:00'))).toEqual('2020-01-29'); - }); - }); -}); diff --git a/spec/javascripts/pretty_time_spec.js b/spec/javascripts/pretty_time_spec.js deleted file mode 100644 index 158cd76dd13..00000000000 --- a/spec/javascripts/pretty_time_spec.js +++ /dev/null @@ -1,135 +0,0 @@ -import { parseSeconds, abbreviateTime, stringifyTime } from '~/lib/utils/pretty_time'; - -function assertTimeUnits(obj, minutes, hours, days, weeks) { - expect(obj.minutes).toBe(minutes); - expect(obj.hours).toBe(hours); - expect(obj.days).toBe(days); - expect(obj.weeks).toBe(weeks); -} - -describe('prettyTime methods', () => { - describe('parseSeconds', () => { - it('should correctly parse a negative value', () => { - const zeroSeconds = parseSeconds(-1000); - - assertTimeUnits(zeroSeconds, 16, 0, 0, 0); - }); - - it('should correctly parse a zero value', () => { - const zeroSeconds = parseSeconds(0); - - assertTimeUnits(zeroSeconds, 0, 0, 0, 0); - }); - - it('should correctly parse a small non-zero second values', () => { - const subOneMinute = parseSeconds(10); - const aboveOneMinute = parseSeconds(100); - const manyMinutes = parseSeconds(1000); - - assertTimeUnits(subOneMinute, 0, 0, 0, 0); - assertTimeUnits(aboveOneMinute, 1, 0, 0, 0); - assertTimeUnits(manyMinutes, 16, 0, 0, 0); - }); - - it('should correctly parse large second values', () => { - const aboveOneHour = parseSeconds(4800); - const aboveOneDay = parseSeconds(110000); - const aboveOneWeek = parseSeconds(25000000); - - assertTimeUnits(aboveOneHour, 20, 1, 0, 0); - assertTimeUnits(aboveOneDay, 33, 6, 3, 0); - assertTimeUnits(aboveOneWeek, 26, 0, 3, 173); - }); - - it('should correctly accept a custom param for hoursPerDay', () => { - const config = { hoursPerDay: 24 }; - - const aboveOneHour = parseSeconds(4800, config); - const aboveOneDay = parseSeconds(110000, config); - const aboveOneWeek = parseSeconds(25000000, config); - - assertTimeUnits(aboveOneHour, 20, 1, 0, 0); - assertTimeUnits(aboveOneDay, 33, 6, 1, 0); - assertTimeUnits(aboveOneWeek, 26, 8, 4, 57); - }); - - it('should correctly accept a custom param for daysPerWeek', () => { - const config = { daysPerWeek: 7 }; - - const aboveOneHour = parseSeconds(4800, config); - const aboveOneDay = parseSeconds(110000, config); - const aboveOneWeek = parseSeconds(25000000, config); - - assertTimeUnits(aboveOneHour, 20, 1, 0, 0); - assertTimeUnits(aboveOneDay, 33, 6, 3, 0); - assertTimeUnits(aboveOneWeek, 26, 0, 0, 124); - }); - - it('should correctly accept custom params for daysPerWeek and hoursPerDay', () => { - const config = { daysPerWeek: 55, hoursPerDay: 14 }; - - const aboveOneHour = parseSeconds(4800, config); - const aboveOneDay = parseSeconds(110000, config); - const aboveOneWeek = parseSeconds(25000000, config); - - assertTimeUnits(aboveOneHour, 20, 1, 0, 0); - assertTimeUnits(aboveOneDay, 33, 2, 2, 0); - assertTimeUnits(aboveOneWeek, 26, 0, 1, 9); - }); - }); - - describe('stringifyTime', () => { - it('should stringify values with all non-zero units', () => { - const timeObject = { - weeks: 1, - days: 4, - hours: 7, - minutes: 20, - }; - - const timeString = stringifyTime(timeObject); - - expect(timeString).toBe('1w 4d 7h 20m'); - }); - - it('should stringify values with some non-zero units', () => { - const timeObject = { - weeks: 0, - days: 4, - hours: 0, - minutes: 20, - }; - - const timeString = stringifyTime(timeObject); - - expect(timeString).toBe('4d 20m'); - }); - - it('should stringify values with no non-zero units', () => { - const timeObject = { - weeks: 0, - days: 0, - hours: 0, - minutes: 0, - }; - - const timeString = stringifyTime(timeObject); - - expect(timeString).toBe('0m'); - }); - }); - - describe('abbreviateTime', () => { - it('should abbreviate stringified times for weeks', () => { - const fullTimeString = '1w 3d 4h 5m'; - - expect(abbreviateTime(fullTimeString)).toBe('1w'); - }); - - it('should abbreviate stringified times for non-weeks', () => { - const fullTimeString = '0w 3d 4h 5m'; - - expect(abbreviateTime(fullTimeString)).toBe('3d'); - }); - }); -}); |