Skip to content

Commit 2384d3b

Browse files
committed
feat(new tool): Duration Calculator
Fix CorentinTh#1037 and CorentinTh#1161
1 parent 80e46c9 commit 2384d3b

File tree

5 files changed

+502
-1
lines changed

5 files changed

+502
-1
lines changed
Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { computeDuration } from './duration-calculator.service';
3+
4+
const zeroResult = {
5+
errors: [],
6+
total: {
7+
days: 0,
8+
hours: 0,
9+
iso8601Duration: 'P0Y0M0DT0H0M0S',
10+
milliseconds: 0,
11+
minutes: 0,
12+
prettified: '0ms',
13+
prettifiedColonNotation: '0:00',
14+
prettifiedDaysColon: '00:00:00',
15+
prettifiedHoursColon: '00:00:00',
16+
prettifiedVerbose: '0 milliseconds',
17+
seconds: 0,
18+
weeks: 0,
19+
years: 0,
20+
},
21+
};
22+
23+
describe('duration-calculator', () => {
24+
describe('computeDuration', () => {
25+
it('should compute correct sum/values', () => {
26+
expect(computeDuration('')).to.deep.eq(zeroResult);
27+
expect(computeDuration('0s')).to.deep.eq(zeroResult);
28+
expect(computeDuration('3600s')).to.deep.eq({
29+
errors: [],
30+
total: {
31+
days: 0.041666666666666664,
32+
hours: 1,
33+
iso8601Duration: 'P0Y0M0DT1H0M0S',
34+
milliseconds: 3600000,
35+
minutes: 60,
36+
prettified: '1h',
37+
prettifiedColonNotation: '1:00:00',
38+
prettifiedDaysColon: '01:00:00',
39+
prettifiedHoursColon: '01:00:00',
40+
prettifiedVerbose: '1 hour',
41+
seconds: 3600,
42+
weeks: 0.005952380952380952,
43+
years: 0.00011415525114155251,
44+
},
45+
});
46+
expect(computeDuration('1h 20m')).to.deep.eq({
47+
errors: [],
48+
total: {
49+
days: 0.05555555555555555,
50+
hours: 1.3333333333333333,
51+
iso8601Duration: 'P0Y0M0DT1H20M0S',
52+
milliseconds: 4800000,
53+
minutes: 80,
54+
prettified: '1h 20m',
55+
prettifiedColonNotation: '1:20:00',
56+
prettifiedDaysColon: '01:20:00',
57+
prettifiedHoursColon: '01:20:00',
58+
prettifiedVerbose: '1 hour 20 minutes',
59+
seconds: 4800,
60+
weeks: 0.007936507936507936,
61+
years: 0.00015220700152207003,
62+
},
63+
});
64+
expect(computeDuration('01:02:03')).to.deep.eq({
65+
errors: [],
66+
total: {
67+
days: 0.043090277777777776,
68+
hours: 1.0341666666666667,
69+
iso8601Duration: 'P0Y0M0DT1H2M3S',
70+
milliseconds: 3723000,
71+
minutes: 62.05,
72+
prettified: '1h 2m 3s',
73+
prettifiedColonNotation: '1:02:03',
74+
prettifiedDaysColon: '01:02:03',
75+
prettifiedHoursColon: '01:02:03',
76+
prettifiedVerbose: '1 hour 2 minutes 3 seconds',
77+
seconds: 3723,
78+
weeks: 0.006155753968253968,
79+
years: 0.00011805555555555556,
80+
},
81+
});
82+
expect(computeDuration('-01:02:03')).to.deep.eq({
83+
errors: [],
84+
total: {
85+
days: -0.043090277777777776,
86+
hours: -1.0341666666666667,
87+
iso8601Duration: 'P0Y0M0DT1H2M3S',
88+
milliseconds: -3723000,
89+
minutes: -62.05,
90+
prettified: '-1h 2m 3s',
91+
prettifiedColonNotation: '-1:02:03',
92+
prettifiedDaysColon: '-2:-3:-3',
93+
prettifiedHoursColon: '-2:-3:-3',
94+
prettifiedVerbose: '-1 hour 2 minutes 3 seconds',
95+
seconds: -3723,
96+
weeks: -0.006155753968253968,
97+
years: -0.00011805555555555556,
98+
},
99+
});
100+
expect(computeDuration('+01:02:05')).to.deep.eq({
101+
errors: [],
102+
total: {
103+
days: 0.04311342592592592,
104+
hours: 1.0347222222222223,
105+
iso8601Duration: 'P0Y0M0DT1H2M5S',
106+
milliseconds: 3725000,
107+
minutes: 62.083333333333336,
108+
prettified: '1h 2m 5s',
109+
prettifiedColonNotation: '1:02:05',
110+
prettifiedDaysColon: '01:02:05',
111+
prettifiedHoursColon: '01:02:05',
112+
prettifiedVerbose: '1 hour 2 minutes 5 seconds',
113+
seconds: 3725,
114+
weeks: 0.006159060846560847,
115+
years: 0.00011811897513952308,
116+
},
117+
});
118+
expect(computeDuration('25s\n+02:40:00.125\n-10s')).to.deep.eq({
119+
errors: [],
120+
total: {
121+
days: 0.11128616898148148,
122+
hours: 2.6708680555555557,
123+
iso8601Duration: 'P0Y0M0DT2H40M15S',
124+
milliseconds: 9615125,
125+
minutes: 160.25208333333333,
126+
prettified: '2h 40m 15.1s',
127+
prettifiedColonNotation: '2:40:15.1',
128+
prettifiedDaysColon: '02:40:15.125',
129+
prettifiedHoursColon: '02:40:15.125',
130+
prettifiedVerbose: '2 hours 40 minutes 15.1 seconds',
131+
seconds: 9615.125,
132+
weeks: 0.01589802414021164,
133+
years: 0.00030489361364789447,
134+
},
135+
});
136+
expect(computeDuration('3d 25s\n+00:40:00\n-10s')).to.deep.eq({
137+
errors: [],
138+
total: {
139+
days: 3.027951388888889,
140+
hours: 72.67083333333333,
141+
iso8601Duration: 'P0Y0M3DT0H40M15S',
142+
milliseconds: 261615000,
143+
minutes: 4360.25,
144+
prettified: '3d 40m 15s',
145+
prettifiedColonNotation: '3:00:40:15',
146+
prettifiedDaysColon: '3d 00:40:15',
147+
prettifiedHoursColon: '72:40:15',
148+
prettifiedVerbose: '3 days 40 minutes 15 seconds',
149+
seconds: 261615,
150+
weeks: 0.4325644841269841,
151+
years: 0.008295757229832572,
152+
},
153+
});
154+
expect(computeDuration('25s\n+12:40\n-10s')).to.deep.eq({
155+
errors: [],
156+
total: {
157+
days: 0.5279513888888889,
158+
hours: 12.670833333333333,
159+
iso8601Duration: 'P0Y0M0DT12H40M15S',
160+
milliseconds: 45615000,
161+
minutes: 760.25,
162+
prettified: '12h 40m 15s',
163+
prettifiedColonNotation: '12:40:15',
164+
prettifiedDaysColon: '12:40:15',
165+
prettifiedHoursColon: '12:40:15',
166+
prettifiedVerbose: '12 hours 40 minutes 15 seconds',
167+
seconds: 45615,
168+
weeks: 0.07542162698412698,
169+
years: 0.0014464421613394217,
170+
},
171+
});
172+
173+
expect(computeDuration('P4DT12H20M20.3S')).to.deep.eq({
174+
errors: [],
175+
total: {
176+
days: 0.5138891238425926,
177+
hours: 12.333338972222222,
178+
iso8601Duration: 'P0Y0M0DT12H20M0S',
179+
milliseconds: 44400020.3,
180+
minutes: 740.0003383333333,
181+
prettified: '12h 20m',
182+
prettifiedColonNotation: '12:20:00',
183+
prettifiedDaysColon: '12:20:00.20.299999997019768',
184+
prettifiedHoursColon: '12:20:00.20.299999997019768',
185+
prettifiedVerbose: '12 hours 20 minutes',
186+
seconds: 44400.0203,
187+
weeks: 0.07341273197751322,
188+
years: 0.0014079154077879248,
189+
},
190+
});
191+
expect(computeDuration('25s\n+PT20H\n-10s')).to.deep.eq({
192+
errors: [],
193+
total: {
194+
days: 0.8335069444444444,
195+
hours: 20.004166666666666,
196+
iso8601Duration: 'P0Y0M0DT20H0M15S',
197+
milliseconds: 72015000,
198+
minutes: 1200.25,
199+
prettified: '20h 15s',
200+
prettifiedColonNotation: '20:00:15',
201+
prettifiedDaysColon: '20:00:15',
202+
prettifiedHoursColon: '20:00:15',
203+
prettifiedVerbose: '20 hours 15 seconds',
204+
seconds: 72015,
205+
weeks: 0.11907242063492063,
206+
years: 0.0022835806697108067,
207+
},
208+
});
209+
});
210+
it('should report invalid lines', () => {
211+
expect(computeDuration('azerr')).to.deep.eq({
212+
errors: [
213+
'azerr',
214+
],
215+
total: {
216+
days: 0,
217+
hours: 0,
218+
iso8601Duration: 'P0Y0M0DT0H0M0S',
219+
milliseconds: 0,
220+
minutes: 0,
221+
prettified: '0ms',
222+
prettifiedColonNotation: '0:00',
223+
prettifiedDaysColon: '00:00:00',
224+
prettifiedHoursColon: '00:00:00',
225+
prettifiedVerbose: '0 milliseconds',
226+
seconds: 0,
227+
weeks: 0,
228+
years: 0,
229+
},
230+
});
231+
expect(computeDuration('25s\ner\n-10s')).to.deep.eq({
232+
errors: [
233+
'er',
234+
],
235+
total: {
236+
days: 0.00017361111111111112,
237+
hours: 0.004166666666666667,
238+
iso8601Duration: 'P0Y0M0DT0H0M15S',
239+
milliseconds: 15000,
240+
minutes: 0.25,
241+
prettified: '15s',
242+
prettifiedColonNotation: '0:15',
243+
prettifiedDaysColon: '00:00:15',
244+
prettifiedHoursColon: '00:00:15',
245+
prettifiedVerbose: '15 seconds',
246+
seconds: 15,
247+
weeks: 0.0000248015873015873,
248+
years: 4.756468797564688e-7,
249+
},
250+
});
251+
expect(computeDuration('25s\n+00:40:00\ner')).to.deep.eq({
252+
errors: [
253+
'er',
254+
],
255+
total: {
256+
days: 0.02806712962962963,
257+
hours: 0.6736111111111112,
258+
iso8601Duration: 'P0Y0M0DT0H40M25S',
259+
milliseconds: 2425000,
260+
minutes: 40.416666666666664,
261+
prettified: '40m 25s',
262+
prettifiedColonNotation: '40:25',
263+
prettifiedDaysColon: '00:40:25',
264+
prettifiedHoursColon: '00:40:25',
265+
prettifiedVerbose: '40 minutes 25 seconds',
266+
seconds: 2425,
267+
weeks: 0.004009589947089947,
268+
years: 0.00007689624556062913,
269+
},
270+
});
271+
expect(computeDuration('ty\n+12:40\n-10s')).to.deep.eq({
272+
errors: [
273+
'ty',
274+
],
275+
total: {
276+
days: 0.5276620370370371,
277+
hours: 12.66388888888889,
278+
iso8601Duration: 'P0Y0M0DT12H39M50S',
279+
milliseconds: 45590000,
280+
minutes: 759.8333333333334,
281+
prettified: '12h 39m 50s',
282+
prettifiedColonNotation: '12:39:50',
283+
prettifiedDaysColon: '12:39:50',
284+
prettifiedHoursColon: '12:39:50',
285+
prettifiedVerbose: '12 hours 39 minutes 50 seconds',
286+
seconds: 45590,
287+
weeks: 0.075380291005291,
288+
years: 0.0014456494165398274,
289+
},
290+
});
291+
});
292+
it('support comment lines (#)', () => {
293+
expect(computeDuration('25s\n # comment\n-10s')).to.deep.eq({
294+
errors: [],
295+
total: {
296+
days: 0.00017361111111111112,
297+
hours: 0.004166666666666667,
298+
iso8601Duration: 'P0Y0M0DT0H0M15S',
299+
milliseconds: 15000,
300+
minutes: 0.25,
301+
prettified: '15s',
302+
prettifiedColonNotation: '0:15',
303+
prettifiedDaysColon: '00:00:15',
304+
prettifiedHoursColon: '00:00:15',
305+
prettifiedVerbose: '15 seconds',
306+
seconds: 15,
307+
weeks: 0.0000248015873015873,
308+
years: 4.756468797564688e-7,
309+
},
310+
});
311+
});
312+
});
313+
});

0 commit comments

Comments
 (0)