Quellcode durchsuchen

feat: utility to format time

Fela Maslen vor 5 Jahren
Ursprung
Commit
b4dc5143a3
4 geänderte Dateien mit 96 neuen und 1 gelöschten Zeilen
  1. 4 0
      gmus/package.json
  2. 19 0
      gmus/src/utils/time.spec.ts
  3. 35 0
      gmus/src/utils/time.ts
  4. 38 1
      gmus/yarn.lock

+ 4 - 0
gmus/package.json

@@ -34,7 +34,9 @@
     "@testing-library/react": "^11.1.0",
     "@testing-library/user-event": "^12.1.10",
     "@types/jest": "^26.0.15",
+    "@types/nock": "^11.1.0",
     "@types/node": "^12.0.0",
+    "@types/pluralize": "^0.0.29",
     "@types/react": "^16.9.53",
     "@types/react-dom": "^16.9.8",
     "@types/styled-components": "^5.1.5",
@@ -45,6 +47,8 @@
     "jest-websocket-mock": "^2.2.0",
     "mock-socket": "^9.0.3",
     "nanoid": "^3.1.20",
+    "nock": "^13.0.5",
+    "pluralize": "^8.0.0",
     "polished": "^4.0.5",
     "prettier": "^2.2.1",
     "react": "^17.0.1",

+ 19 - 0
gmus/src/utils/time.spec.ts

@@ -0,0 +1,19 @@
+import { formatTime } from './time';
+
+describe(formatTime.name, () => {
+  it.each`
+    case                       | input     | output
+    ${'zero'}                  | ${0}      | ${'00:00'}
+    ${null}                    | ${null}   | ${''}
+    ${'less than ten seconds'} | ${7}      | ${'00:07'}
+    ${'less than one minute'}  | ${26}     | ${'00:26'}
+    ${'less than 10 minutes'}  | ${593}    | ${'09:53'}
+    ${'less than one hour'}    | ${3176}   | ${'52:56'}
+    ${'more than one hour'}    | ${3615}   | ${'1:00:15'}
+    ${'more than one day'}     | ${86465}  | ${'1 day, 01:05'}
+    ${'negative values'}       | ${-86465} | ${'-1 day, 01:05'}
+  `('should handle case: $case', ({ input, output }) => {
+    expect.assertions(1);
+    expect(formatTime(input)).toBe(output);
+  });
+});

+ 35 - 0
gmus/src/utils/time.ts

@@ -0,0 +1,35 @@
+import pluralize from 'pluralize';
+
+export function formatTime(seconds: number | null): string {
+  if (seconds == null) {
+    return '';
+  }
+
+  const totalSecondsAbsolute = Math.abs(seconds);
+  const sign = seconds < 0 ? '-' : '';
+
+  const hours = Math.floor(totalSecondsAbsolute / 3600);
+  const afterHours = totalSecondsAbsolute % 3600;
+
+  const minutes = Math.floor(afterHours / 60);
+  const remainingSeconds = afterHours % 60;
+
+  const minutesSeconds = `${minutes
+    .toFixed()
+    .padStart(2, '0')}:${remainingSeconds.toFixed().padStart(2, '0')}`;
+
+  if (!hours) {
+    return `${sign}${minutesSeconds}`;
+  }
+
+  const days = Math.floor(hours / 24);
+  const remainingHours = hours % 24;
+
+  const time = remainingHours ? `${remainingHours.toFixed()}:${minutesSeconds}` : minutesSeconds;
+
+  if (!days) {
+    return `${sign}${time}`;
+  }
+
+  return `${sign}${pluralize('day', days, true)}, ${time}`;
+}

+ 38 - 1
gmus/yarn.lock

@@ -1898,6 +1898,13 @@
   resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
   integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
 
+"@types/nock@^11.1.0":
+  version "11.1.0"
+  resolved "https://registry.yarnpkg.com/@types/nock/-/nock-11.1.0.tgz#0a8c1056a31ba32a959843abccf99626dd90a538"
+  integrity sha512-jI/ewavBQ7X5178262JQR0ewicPAcJhXS/iFaNJl0VHLfyosZ/kwSrsa6VNQNSO8i9d8SqdRgOtZSOKJ/+iNMw==
+  dependencies:
+    nock "*"
+
 "@types/node@*":
   version "14.14.9"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.9.tgz#04afc9a25c6ff93da14deabd65dc44485b53c8d6"
@@ -1918,6 +1925,11 @@
   resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
   integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
 
+"@types/pluralize@^0.0.29":
+  version "0.0.29"
+  resolved "https://registry.yarnpkg.com/@types/pluralize/-/pluralize-0.0.29.tgz#6ffa33ed1fc8813c469b859681d09707eb40d03c"
+  integrity sha512-BYOID+l2Aco2nBik+iYS4SZX0Lf20KPILP5RGmM1IgzdwNdTs0eebiFriOPcej1sX9mLnSoiNte5zcFxssgpGA==
+
 "@types/prettier@^2.0.0":
   version "2.1.5"
   resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.5.tgz#b6ab3bba29e16b821d84e09ecfaded462b816b00"
@@ -6976,7 +6988,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
   resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
   integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
 
-json-stringify-safe@~5.0.1:
+json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
   integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
@@ -7189,6 +7201,11 @@ lodash.memoize@^4.1.2:
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
   integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
 
+lodash.set@^4.3.2:
+  version "4.3.2"
+  resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
+  integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
+
 lodash.sortby@^4.7.0:
   version "4.7.0"
   resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
@@ -7658,6 +7675,16 @@ no-case@^3.0.3:
     lower-case "^2.0.1"
     tslib "^1.10.0"
 
+nock@*, nock@^13.0.5:
+  version "13.0.5"
+  resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.5.tgz#a618c6f86372cb79fac04ca9a2d1e4baccdb2414"
+  integrity sha512-1ILZl0zfFm2G4TIeJFW0iHknxr2NyA+aGCMTjDVUsBY4CkMRispF1pfIYkTRdAR/3Bg+UzdEuK0B6HczMQZcCg==
+  dependencies:
+    debug "^4.1.0"
+    json-stringify-safe "^5.0.1"
+    lodash.set "^4.3.2"
+    propagate "^2.0.0"
+
 node-forge@^0.10.0:
   version "0.10.0"
   resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
@@ -8289,6 +8316,11 @@ pkg-up@3.1.0:
   dependencies:
     find-up "^3.0.0"
 
+pluralize@^8.0.0:
+  version "8.0.0"
+  resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
+  integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
+
 pnp-webpack-plugin@1.6.4:
   version "1.6.4"
   resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149"
@@ -9083,6 +9115,11 @@ prop-types@^15.7.2:
     object-assign "^4.1.1"
     react-is "^16.8.1"
 
+propagate@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45"
+  integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==
+
 proxy-addr@~2.0.5:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"