Skip to content

Commit 50c707e

Browse files
committed
Move TimelineHours logic to a presenter and add tests
1 parent c2848b0 commit 50c707e

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

src/timeline/TimelineHours.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, {useCallback, useMemo} from 'react';
22
import {View, Text, TouchableWithoutFeedback, ViewStyle, TextStyle, Dimensions, StyleSheet} from 'react-native';
33
import range from 'lodash/range';
44
import {HOUR_BLOCK_HEIGHT} from './Packer';
5+
import {buildTimeString, calcTimeByPosition} from './helpers/presenter';
56

67
const {width: dimensionWidth} = Dimensions.get('window');
78

@@ -40,13 +41,9 @@ const TimelineHours = (props: TimelineHoursProps) => {
4041

4142
const handleBackgroundPress = useCallback(event => {
4243
const yPosition = event.nativeEvent.locationY;
43-
const halfHourBlockHeight = HOUR_BLOCK_HEIGHT / 2;
44-
let time = yPosition / halfHourBlockHeight / 2;
45-
time = Math.round(time * 2) / 2;
44+
const {hour, minutes} = calcTimeByPosition(yPosition, HOUR_BLOCK_HEIGHT);
4645

47-
const hour = Math.floor(time);
48-
const minutes = (time - Math.floor(time)) * 60;
49-
const timeString = `${hour.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`;
46+
const timeString = buildTimeString(hour, minutes);
5047
onBackgroundLongPress?.(timeString, {hour, minutes});
5148
}, []);
5249

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import * as uut from '../helpers/presenter';
2+
3+
describe('timeline presenter', () => {
4+
describe('calcTimeByPosition', () => {
5+
it('should return hour/minutes by position - basic case 1', () => {
6+
const {hour, minutes} = uut.calcTimeByPosition(300, 100);
7+
expect(hour).toBe(3);
8+
expect(minutes).toBe(0);
9+
});
10+
11+
it('should return hour/minutes by position - basic case 2', () => {
12+
const {hour, minutes} = uut.calcTimeByPosition(350, 100);
13+
expect(hour).toBe(3);
14+
expect(minutes).toBe(30);
15+
});
16+
17+
it('should round time to nearest 30 minutes block', () => {
18+
const time1 = uut.calcTimeByPosition(310, 100);
19+
expect(time1.hour).toBe(3);
20+
expect(time1.minutes).toBe(0);
21+
22+
const time2 = uut.calcTimeByPosition(280, 100);
23+
expect(time2.hour).toBe(3);
24+
expect(time2.minutes).toBe(0);
25+
26+
const time3 = uut.calcTimeByPosition(440, 100);
27+
expect(time3.hour).toBe(4);
28+
expect(time3.minutes).toBe(30);
29+
30+
const time4 = uut.calcTimeByPosition(1488, 100);
31+
expect(time4.hour).toBe(15);
32+
expect(time4.minutes).toBe(0);
33+
});
34+
35+
it('should handle different hour block heights', () => {
36+
const time1 = uut.calcTimeByPosition(350, 85);
37+
expect(time1.hour).toBe(4);
38+
expect(time1.minutes).toBe(0);
39+
40+
const time2 = uut.calcTimeByPosition(350, 145);
41+
expect(time2.hour).toBe(2);
42+
expect(time2.minutes).toBe(30);
43+
});
44+
});
45+
46+
describe('buildTimeString', () => {
47+
it('should construct time string based on given hour/mins', () => {
48+
expect(uut.buildTimeString(3, 12)).toBe('03:12:00');
49+
expect(uut.buildTimeString(23, 55)).toBe('23:55:00');
50+
});
51+
52+
it('should padding hour/minutes with zeroes', () => {
53+
expect(uut.buildTimeString(3, 0)).toBe('03:00:00');
54+
expect(uut.buildTimeString(9, 5)).toBe('09:05:00');
55+
});
56+
57+
it('should default undefined hour/min to zeroes', () => {
58+
expect(uut.buildTimeString(undefined, 30)).toBe('00:30:00');
59+
expect(uut.buildTimeString(9, undefined)).toBe('09:00:00');
60+
});
61+
});
62+
});

src/timeline/helpers/presenter.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export function calcTimeByPosition(yPosition: number, hourBlockHeight: number) {
2+
const halfHourBlockHeight = hourBlockHeight / 2;
3+
let time = yPosition / halfHourBlockHeight / 2;
4+
time = Math.round(time * 2) / 2;
5+
6+
const hour = Math.floor(time);
7+
const minutes = (time - Math.floor(time)) * 60;
8+
return {hour, minutes};
9+
}
10+
11+
export function buildTimeString(hour = 0, minutes = 0) {
12+
return `${hour.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`;
13+
}

0 commit comments

Comments
 (0)