Browse Source

chore(core/utils): Add typings to datemath.ts (#16195)

* Add typings

* Remove explicit cast
Andrej Ocenas 6 years ago
parent
commit
a978e28e7c

+ 2 - 2
public/app/core/specs/datemath.test.ts

@@ -12,8 +12,8 @@ describe('DateMath', () => {
   let clock;
   let clock;
 
 
   describe('errors', () => {
   describe('errors', () => {
-    it('should return undefined if passed something falsy', () => {
-      expect(dateMath.parse(false)).toBe(undefined);
+    it('should return undefined if passed empty string', () => {
+      expect(dateMath.parse('')).toBe(undefined);
     });
     });
 
 
     it('should return undefined if I pass an operator besides [+-/]', () => {
     it('should return undefined if I pass an operator besides [+-/]', () => {

+ 64 - 35
public/app/core/utils/datemath.ts

@@ -3,50 +3,73 @@ import moment from 'moment';
 
 
 const units = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
 const units = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
 
 
-export function parse(text, roundUp?, timezone?) {
+type Timezone = 'utc';
+
+/**
+ * Parses different types input to a moment instance. There is a specific formatting language that can be used
+ * if text arg is string. See unit tests for examples.
+ * @param text
+ * @param roundUp See parseDateMath function.
+ * @param timezone Only string 'utc' is acceptable here, for anything else, local timezone is used.
+ */
+export function parse(
+  text: string | moment.Moment | Date,
+  roundUp?: boolean,
+  timezone?: Timezone
+): moment.Moment | undefined {
   if (!text) {
   if (!text) {
     return undefined;
     return undefined;
   }
   }
-  if (moment.isMoment(text)) {
-    return text;
-  }
-  if (_.isDate(text)) {
-    return moment(text);
-  }
-
-  let time;
-  let mathString = '';
-  let index;
-  let parseString;
 
 
-  if (text.substring(0, 3) === 'now') {
-    if (timezone === 'utc') {
-      time = moment.utc();
-    } else {
-      time = moment();
+  if (typeof text !== 'string') {
+    if (moment.isMoment(text)) {
+      return text;
+    }
+    if (_.isDate(text)) {
+      return moment(text);
     }
     }
-    mathString = text.substring('now'.length);
+    // We got some non string which is not a moment nor Date. TS should be able to check for that but not always.
+    return undefined;
   } else {
   } else {
-    index = text.indexOf('||');
-    if (index === -1) {
-      parseString = text;
-      mathString = ''; // nothing else
+    let time;
+    let mathString = '';
+    let index;
+    let parseString;
+
+    if (text.substring(0, 3) === 'now') {
+      if (timezone === 'utc') {
+        time = moment.utc();
+      } else {
+        time = moment();
+      }
+      mathString = text.substring('now'.length);
     } else {
     } else {
-      parseString = text.substring(0, index);
-      mathString = text.substring(index + 2);
+      index = text.indexOf('||');
+      if (index === -1) {
+        parseString = text;
+        mathString = ''; // nothing else
+      } else {
+        parseString = text.substring(0, index);
+        mathString = text.substring(index + 2);
+      }
+      // We're going to just require ISO8601 timestamps, k?
+      time = moment(parseString, moment.ISO_8601);
     }
     }
-    // We're going to just require ISO8601 timestamps, k?
-    time = moment(parseString, moment.ISO_8601);
-  }
 
 
-  if (!mathString.length) {
-    return time;
-  }
+    if (!mathString.length) {
+      return time;
+    }
 
 
-  return parseDateMath(mathString, time, roundUp);
+    return parseDateMath(mathString, time, roundUp);
+  }
 }
 }
 
 
-export function isValid(text) {
+/**
+ * Checks if text is a valid date which in this context means that it is either a Moment instance or it can be parsed
+ * by parse function. See parse function to see what is considered acceptable.
+ * @param text
+ */
+export function isValid(text: string | moment.Moment): boolean {
   const date = parse(text);
   const date = parse(text);
   if (!date) {
   if (!date) {
     return false;
     return false;
@@ -59,7 +82,13 @@ export function isValid(text) {
   return false;
   return false;
 }
 }
 
 
-export function parseDateMath(mathString, time, roundUp?) {
+/**
+ * Parses math part of the time string and shifts supplied time according to that math. See unit tests for examples.
+ * @param mathString
+ * @param time
+ * @param roundUp If true it will round the time to endOf time unit, otherwise to startOf time unit.
+ */
+export function parseDateMath(mathString: string, time: moment.Moment, roundUp?: boolean): moment.Moment | undefined {
   const dateTime = time;
   const dateTime = time;
   let i = 0;
   let i = 0;
   const len = mathString.length;
   const len = mathString.length;
@@ -80,13 +109,13 @@ export function parseDateMath(mathString, time, roundUp?) {
       return undefined;
       return undefined;
     }
     }
 
 
-    if (isNaN(mathString.charAt(i))) {
+    if (isNaN(parseInt(mathString.charAt(i), 10))) {
       num = 1;
       num = 1;
     } else if (mathString.length === 2) {
     } else if (mathString.length === 2) {
       num = mathString.charAt(i);
       num = mathString.charAt(i);
     } else {
     } else {
       const numFrom = i;
       const numFrom = i;
-      while (!isNaN(mathString.charAt(i))) {
+      while (!isNaN(parseInt(mathString.charAt(i), 10))) {
         i++;
         i++;
         if (i > 10) {
         if (i > 10) {
           return undefined;
           return undefined;

+ 1 - 1
public/app/features/explore/TimePicker.tsx

@@ -120,7 +120,7 @@ export default class TimePicker extends PureComponent<TimePickerProps, TimePicke
     } else if (direction === 1) {
     } else if (direction === 1) {
       nextTo = to.valueOf() + timespan;
       nextTo = to.valueOf() + timespan;
       nextFrom = from.valueOf() + timespan;
       nextFrom = from.valueOf() + timespan;
-      if (nextTo > Date.now() && to < Date.now()) {
+      if (nextTo > Date.now() && to.valueOf() < Date.now()) {
         nextTo = Date.now();
         nextTo = Date.now();
         nextFrom = from.valueOf();
         nextFrom = from.valueOf();
       }
       }