diff --git a/.gitignore b/.gitignore index d84eab43f..7a597a038 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ node_modules/ .pnp.js # testing -/coverage +coverage/ # production build/ diff --git a/client/src/common/components/countdown/Countdown.jsx b/client/src/common/components/countdown/Countdown.jsx index a6b42b29b..740eae82c 100644 --- a/client/src/common/components/countdown/Countdown.jsx +++ b/client/src/common/components/countdown/Countdown.jsx @@ -1,13 +1,14 @@ import { memo } from 'react'; -import { formatDisplay } from 'common/dateConfig'; +import { formatDisplay } from 'common/utils/dateConfig'; import styles from './Countdown.module.css'; const Countdown = ({ time, small, negative, hideZeroHours }) => { - let display = '-- : -- : --'; - // prepare display string - if (time != null && !isNaN(time)) - display = formatDisplay(Math.abs(time), hideZeroHours); + const display = + time != null && !isNaN(time) + ? formatDisplay(time, hideZeroHours) + : '-- : -- : --'; + const colour = negative ? '#ff7597' : '#fffffa'; return ( diff --git a/client/src/common/components/eventTimes/EventTimesVertical.jsx b/client/src/common/components/eventTimes/EventTimesVertical.jsx index 244054503..3e0ea8357 100644 --- a/client/src/common/components/eventTimes/EventTimesVertical.jsx +++ b/client/src/common/components/eventTimes/EventTimesVertical.jsx @@ -1,6 +1,6 @@ import EditableTimer from 'common/input/EditableTimer'; import { showWarningToast } from 'common/helpers/toastManager'; -import { stringFromMillis } from 'common/dateConfig'; +import { stringFromMillis } from 'common/utils/dateConfig'; const label = { fontSize: '0.75em', diff --git a/client/src/common/components/views/TodayItem.jsx b/client/src/common/components/views/TodayItem.jsx index 3238e9e2c..73da1d3f1 100644 --- a/client/src/common/components/views/TodayItem.jsx +++ b/client/src/common/components/views/TodayItem.jsx @@ -1,4 +1,4 @@ -import { stringFromMillis } from 'common/dateConfig'; +import { stringFromMillis } from 'common/utils/dateConfig'; import style from './Paginator.module.css'; export default function TodayItem(props) { const { selected, timeStart, timeEnd, title, backstageEvent } = props; diff --git a/client/src/common/dateConfig.js b/client/src/common/dateConfig.js deleted file mode 100644 index 857812c4f..000000000 --- a/client/src/common/dateConfig.js +++ /dev/null @@ -1,49 +0,0 @@ -export const timeFormat = 'HH:mm'; -export const timeFormatSeconds = 'HH:mm:ss'; - -// time string from miliseconds -export const stringFromMillis = ( - ms, - showSeconds = true, - delim = ':', - ifNull = '...' -) => { - if (ms === null || isNaN(ms)) return ifNull; - const showWith0 = (value) => (value < 10 ? `0${value}` : value); - const hours = showWith0(Math.floor(((ms / (1000 * 60 * 60)) % 60) % 24)); - const minutes = showWith0(Math.floor((ms / (1000 * 60)) % 60)); - const seconds = showWith0(Math.floor((ms / 1000) % 60)); - - return showSeconds - ? `${ - parseInt(hours) ? `${hours}${delim}` : `00${delim}` - }${minutes}${delim}${seconds}` - : `${parseInt(hours) ? `${hours}` : '00'}${delim}${minutes}`; -}; - -// another go at simpler string formatting (counters) -export function formatDisplay(seconds, hideZero) { - const format = (val) => `0${Math.floor(val)}`.slice(-2); - const hours = seconds / 3600; - const minutes = (seconds % 3600) / 60; - - if (hideZero && hours < 1) - return [minutes, seconds % 60].map(format).join(':'); - else return [hours, minutes, seconds % 60].map(format).join(':'); -} - -// millis to seconds -export const millisToSeconds = (millis) => { - return Math.floor(millis / 1000); -}; - -// millis to minutes -export const millisToMinutes = (millis) => { - return Math.floor(millis / 60000); -}; - -// timeStringToMillis -export const timeStringToMillis = (string) => { - let time = string.split(':'); - return time[0] * 3600000 + time[1] * 60000; -}; diff --git a/client/src/common/input/EditableTimer.jsx b/client/src/common/input/EditableTimer.jsx index 2c39dd6d8..0919ab44e 100644 --- a/client/src/common/input/EditableTimer.jsx +++ b/client/src/common/input/EditableTimer.jsx @@ -1,10 +1,6 @@ import { Editable, EditableInput, EditablePreview } from '@chakra-ui/editable'; import { useEffect, useState } from 'react'; -import { - timeFormat, - stringFromMillis, - timeStringToMillis, -} from '../dateConfig'; +import { stringFromMillis, timeStringToMillis } from '../utils/dateConfig'; import { showErrorToast } from '../helpers/toastManager'; import style from './EditableTimer.module.css'; @@ -16,7 +12,7 @@ export default function EditableTimer(props) { useEffect(() => { if (time == null) return; try { - setValue(stringFromMillis(time + delay, false)); + setValue(stringFromMillis(time + delay)); } catch (error) { showErrorToast('Error parsing date', error.text); } @@ -24,9 +20,8 @@ export default function EditableTimer(props) { const validateValue = (value) => { const success = handleSubmit(value); - if (success) setValue(value); - else setValue(stringFromMillis(time + delay, false)); + else setValue(stringFromMillis(time + delay, true)); }; const handleSubmit = (value) => { @@ -34,13 +29,13 @@ export default function EditableTimer(props) { if (value === '') return false; // Time now and time submitedVal - const original = stringFromMillis(time + delay, false); + const original = stringFromMillis(time + delay, true); // check if time is different from before if (value === original) return false; // convert to millis object - const millis = timeStringToMillis(value, timeFormat); + const millis = timeStringToMillis(value); // validate with parent if (!validate(name, millis)) return false; @@ -55,12 +50,13 @@ export default function EditableTimer(props) { setValue(v)} onSubmit={(v) => validateValue(v)} + onCancel={() => setValue(stringFromMillis(time + delay, true))} value={value} - placeholder='--:--' + placeholder='--:--:--' className={delay > 0 ? style.delayedEditable : style.editable} > - + ); } diff --git a/client/src/common/input/EditableTimer.module.css b/client/src/common/input/EditableTimer.module.css index d10c24948..0a4392446 100644 --- a/client/src/common/input/EditableTimer.module.css +++ b/client/src/common/input/EditableTimer.module.css @@ -1,9 +1,10 @@ .editable, .delayedEditable { - background-color: rgba(255, 255, 255, 0.05); + background-color: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.05); border-radius: 4px; - width: 5em; + width: 6.5em; + letter-spacing: 1px; height: fit-content; text-align: center; diff --git a/client/src/common/utils/__tests__/dateConfig.test.js b/client/src/common/utils/__tests__/dateConfig.test.js new file mode 100644 index 000000000..3595d09ce --- /dev/null +++ b/client/src/common/utils/__tests__/dateConfig.test.js @@ -0,0 +1,216 @@ +import { + formatDisplay, + millisToMinutes, + millisToSeconds, + timeStringToMillis, +} from '../dateConfig'; + +describe('test string from formatDisplay function', () => { + it('test with null values', () => { + const t = { val: null, result: '00:00:00' }; + expect(formatDisplay(t.val, false)).toBe(t.result); + }); + + it('test with valid millis', () => { + const t = { val: 3600, result: '01:00:00' }; + expect(formatDisplay(t.val, false)).toBe(t.result); + }); + + it('test with negative millis', () => { + const t = { val: -3600, result: '01:00:00' }; + expect(formatDisplay(t.val, false)).toBe(t.result); + }); + + it('test with 0', () => { + const t = { val: 0, result: '00:00:00' }; + expect(formatDisplay(t.val, false)).toBe(t.result); + }); + + it('test with -0', () => { + const t = { val: -0, result: '00:00:00' }; + expect(formatDisplay(t.val, false)).toBe(t.result); + }); + + it('test with 86400 (24 hours)', () => { + const t = { val: 86400, result: '00:00:00' }; + expect(formatDisplay(t.val, false)).toBe(t.result); + }); + + it('test with 86401 (24 hours and 1 second)', () => { + const t = { val: 86401, result: '00:00:01' }; + expect(formatDisplay(t.val, false)).toBe(t.result); + }); + + it('test with -86401 (-24 hours and 1 second)', () => { + const t = { val: -86401, result: '00:00:01' }; + expect(formatDisplay(t.val, false)).toBe(t.result); + }); +}); + +describe('test string from formatDisplay function with hidezero', () => { + it('test with null values', () => { + const t = { val: null, result: '00:00' }; + expect(formatDisplay(t.val, true)).toBe(t.result); + }); + + it('test with valid millis', () => { + const t = { val: 3600, result: '01:00:00' }; + expect(formatDisplay(t.val, true)).toBe(t.result); + }); + + it('test with negative millis', () => { + const t = { val: -3600, result: '01:00:00' }; + expect(formatDisplay(t.val, true)).toBe(t.result); + }); + + it('test with 0', () => { + const t = { val: 0, result: '00:00' }; + expect(formatDisplay(t.val, true)).toBe(t.result); + }); + + it('test with -0', () => { + const t = { val: -0, result: '00:00' }; + expect(formatDisplay(t.val, true)).toBe(t.result); + }); + + it('test with 86400 (24 hours)', () => { + const t = { val: 86400, result: '00:00' }; + expect(formatDisplay(t.val, true)).toBe(t.result); + }); + + it('test with 86401 (24 hours and 1 second)', () => { + const t = { val: 86401, result: '00:01' }; + expect(formatDisplay(t.val, true)).toBe(t.result); + }); + + it('test with -86401 (-24 hours and 1 second)', () => { + const t = { val: -86401, result: '00:01' }; + expect(formatDisplay(t.val, true)).toBe(t.result); + }); +}); + +describe('test millisToSeconds function', () => { + it('test with null values', () => { + const t = { val: null, result: 0 }; + expect(millisToSeconds(t.val, false)).toBe(t.result); + }); + + it('test with valid millis', () => { + const t = { val: 3600000, result: 3600 }; + expect(millisToSeconds(t.val, false)).toBe(t.result); + }); + + it('test with negative millis', () => { + const t = { val: -3600000, result: -3600 }; + expect(millisToSeconds(t.val, false)).toBe(t.result); + }); + + it('test with 0', () => { + const t = { val: 0, result: 0 }; + expect(millisToSeconds(t.val, false)).toBe(t.result); + }); + + it('test with -0', () => { + const t = { val: -0, result: -0 }; + expect(millisToSeconds(t.val, false)).toBe(t.result); + }); + + it('test with 86401000 (24 hours and 1 second)', () => { + const t = { val: 86401000, result: 86401 }; + expect(millisToSeconds(t.val, false)).toBe(t.result); + }); + + it('test with -86401000 (-24 hours and 1 second)', () => { + const t = { val: -86401000, result: -86401 }; + expect(millisToSeconds(t.val, false)).toBe(t.result); + }); +}); + +describe('test millisToMinutes function', () => { + it('test with null values', () => { + const t = { val: null, result: 0 }; + expect(millisToMinutes(t.val, false)).toBe(t.result); + }); + + it('test with valid millis', () => { + const t = { val: 3600000, result: 60 }; + expect(millisToMinutes(t.val, false)).toBe(t.result); + }); + + it('test with negative millis', () => { + const t = { val: -3600000, result: -60 }; + expect(millisToMinutes(t.val, false)).toBe(t.result); + }); + + it('test with 0', () => { + const t = { val: 0, result: 0 }; + expect(millisToMinutes(t.val, false)).toBe(t.result); + }); + + it('test with -0', () => { + const t = { val: -0, result: -0 }; + expect(millisToMinutes(t.val, false)).toBe(t.result); + }); + + it('test with 86401000 (24 hours and 1 second)', () => { + const t = { val: 86401000, result: 1440 }; + expect(millisToMinutes(t.val, false)).toBe(t.result); + }); + + it('test with -86401000 (-24 hours and 1 second)', () => { + const t = { val: -86401000, result: -1440 }; + expect(millisToMinutes(t.val, false)).toBe(t.result); + }); +}); + +describe('test timeStringToMillis function', () => { + it('test with null', () => { + const t = { val: null, result: 0 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 00:00:00', () => { + const t = { val: '00:00:00', result: 0 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with -00:00:00', () => { + const t = { val: '-00:00:00', result: 0 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 00:00:01', () => { + const t = { val: '00:00:01', result: 1000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with -00:00:01', () => { + const t = { val: '-00:00:01', result: 1000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 01:00:01', () => { + const t = { val: '01:00:01', result: 3601000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 24:00:01', () => { + const t = { val: '24:00:01', result: 86401000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 00:00:5', () => { + const t = { val: '00:00:5', result: 5000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 00:1:00', () => { + const t = { val: '00:1:00', result: 60000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 1:00:00', () => { + const t = { val: '1:00:00', result: 3600000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); +}); diff --git a/client/src/common/utils/dateConfig.js b/client/src/common/utils/dateConfig.js new file mode 100644 index 000000000..7cc62d4e6 --- /dev/null +++ b/client/src/common/utils/dateConfig.js @@ -0,0 +1,97 @@ +export const timeFormat = 'HH:mm'; +export const timeFormatSeconds = 'HH:mm:ss'; + +const mts = 1000; // millis to seconds +const mtm = 1000 * 60; // millis to minutes +const mth = 1000 * 60 * 60; // millis to hours +const mtd = 1000 * 60 * 60 * 24; // millis to days + +/** + * @description Converts milliseconds to string representing time + * @param {number} ms - time in milliseconds + * @param {boolean} showSeconds - wether to show the seconds + * @param {string} delim - character between HH MM SS + * @param {string} ifNull - what to return if value is null + * @returns {string} String representing time 00:12:02 + */ + +// This is shared and tested in backend in time.js +export const stringFromMillis = ( + ms, + showSeconds = true, + delim = ':', + ifNull = '...' +) => { + if (ms === null || isNaN(ms)) return ifNull; + const isNegative = ms < 0 ? '-' : ''; + const showWith0 = (value) => (value < 10 ? `0${value}` : value); + const hours = showWith0(Math.floor(((ms / mth) % 60) % 24)); + const minutes = showWith0(Math.floor((ms / mtm) % 60)); + const seconds = showWith0(Math.floor((ms / mts) % 60)); + + return showSeconds + ? `${isNegative}${ + parseInt(hours) ? `${hours}${delim}` : `00${delim}` + }${minutes}${delim}${seconds}` + : `${isNegative}${parseInt(hours) ? `${hours}` : '00'}${delim}${minutes}`; +}; + +/** + * another go at simpler string formatting (counters) + * @description Converts seconds to string representing time + * @param {number} seconds - time in seconds + * @param {boolean} hideZero - wether to show hours in case its 00 + * @returns {string} String representing absolute time 00:12:02 + */ + +export function formatDisplay(seconds, hideZero) { + // add an extra 0 if necessary + const format = (val) => `0${Math.floor(val)}`.slice(-2); + + const s = Math.abs(seconds); + const hours = Math.floor((s / 3600) % 24); + const minutes = Math.floor((s % 3600) / 60); + + if (hideZero && hours < 1) return [minutes, s % 60].map(format).join(':'); + else return [hours, minutes, s % 60].map(format).join(':'); +} + +/** + * @description Converts milliseconds to seconds + * @param {number} millis - time in seconds + * @param {boolean} hideZero - wether to show hours in case its 00 + * @returns {number} Amount in seconds + */ + +// millis to seconds +export const millisToSeconds = (millis) => { + return millis < 0 ? Math.ceil(millis / mts) : Math.floor(millis / mts); +}; + +/** + * @description Converts milliseconds to seconds + * @param {number} millis - time in seconds + * @param {boolean} hideZero - wether to show hours in case its 00 + * @returns {number} Amount in seconds + */ + +// millis to minutes +export const millisToMinutes = (millis) => { + return millis < 0 ? Math.ceil(millis / mtm) : Math.floor(millis / mtm); +}; + +/** + * @description Converts timestring to milliseconds + * @param {string} string - time string "23:00:12" + * @returns {number} Amount in milliseconds + */ + +// timeStringToMillis +export const timeStringToMillis = (string) => { + if (typeof string !== 'string') return 0; + const time = string.split(':'); + if (time.length === 2) return Math.abs(time[0]) * mth + time[1]; + if (time.length === 3) + return Math.abs(time[0]) * mth + time[1] * mtm + time[2] * mts; + else return 0; +}; diff --git a/client/src/features/control/PlaybackTimer.jsx b/client/src/features/control/PlaybackTimer.jsx index 4b44332a8..e2fa3f9da 100644 --- a/client/src/features/control/PlaybackTimer.jsx +++ b/client/src/features/control/PlaybackTimer.jsx @@ -1,6 +1,6 @@ import style from './PlaybackControl.module.css'; import Countdown from 'common/components/countdown/Countdown'; -import { stringFromMillis } from 'common/dateConfig'; +import { stringFromMillis } from 'common/utils/dateConfig'; import { Tooltip } from '@chakra-ui/react'; import { Button } from '@chakra-ui/button'; import { memo } from 'react'; diff --git a/client/src/features/editors/list/DelayBlock.jsx b/client/src/features/editors/list/DelayBlock.jsx index a2b9e7bfe..1a9811e82 100644 --- a/client/src/features/editors/list/DelayBlock.jsx +++ b/client/src/features/editors/list/DelayBlock.jsx @@ -1,6 +1,6 @@ import { Draggable } from 'react-beautiful-dnd'; import { FiMoreVertical } from 'react-icons/fi'; -import { millisToMinutes } from 'common/dateConfig'; +import { millisToMinutes } from 'common/utils/dateConfig'; import ActionButtons from './ActionButtons'; import DeleteIconBtn from 'common/components/buttons/DeleteIconBtn'; import ApplyIconBtn from 'common/components/buttons/ApplyIconBtn'; diff --git a/client/src/features/editors/list/EventBlock.jsx b/client/src/features/editors/list/EventBlock.jsx index bf51923ec..bc047f2f4 100644 --- a/client/src/features/editors/list/EventBlock.jsx +++ b/client/src/features/editors/list/EventBlock.jsx @@ -8,7 +8,7 @@ import EditableText from 'common/input/EditableText'; import ActionButtons from './ActionButtons'; import PublicIconBtn from 'common/components/buttons/PublicIconBtn'; import DeleteIconBtn from 'common/components/buttons/DeleteIconBtn'; -import { millisToMinutes } from 'common/dateConfig'; +import { millisToMinutes } from 'common/utils/dateConfig'; import style from './EventBlock.module.css'; import { SelectCollapse, HandleCollapse } from 'app/context/collapseAtom'; import { useAtom } from 'jotai'; diff --git a/client/src/features/viewers/ViewWrapper.jsx b/client/src/features/viewers/ViewWrapper.jsx index ce45c6171..6d90c0a7e 100644 --- a/client/src/features/viewers/ViewWrapper.jsx +++ b/client/src/features/viewers/ViewWrapper.jsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { fetchAllEvents } from 'app/api/eventsApi'; import { fetchEvent } from 'app/api/eventApi'; import { useSocket } from 'app/context/socketContext'; -import { stringFromMillis } from 'common/dateConfig'; +import { stringFromMillis } from 'common/utils/dateConfig'; import { useFetch } from 'app/hooks/useFetch'; import { EVENTS_TABLE, EVENT_TABLE } from 'app/api/apiConstants'; diff --git a/client/src/features/viewers/backstage/StageManager.jsx b/client/src/features/viewers/backstage/StageManager.jsx index 4c844edaa..d5ddab987 100644 --- a/client/src/features/viewers/backstage/StageManager.jsx +++ b/client/src/features/viewers/backstage/StageManager.jsx @@ -1,5 +1,5 @@ import QRCode from 'react-qr-code'; -import { formatDisplay } from 'common/dateConfig'; +import { formatDisplay } from 'common/utils/dateConfig'; import style from './StageManager.module.css'; import Paginator from 'common/components/views/Paginator'; import NavLogo from 'common/components/nav/NavLogo'; diff --git a/client/src/features/viewers/production/Pip.jsx b/client/src/features/viewers/production/Pip.jsx index b0b5492f8..1142511a2 100644 --- a/client/src/features/viewers/production/Pip.jsx +++ b/client/src/features/viewers/production/Pip.jsx @@ -4,7 +4,7 @@ import Paginator from 'common/components/views/Paginator'; import NavLogo from 'common/components/nav/NavLogo'; import { AnimatePresence, motion } from 'framer-motion'; import { useEffect, useLayoutEffect, useRef, useState } from 'react'; -import { formatDisplay } from 'common/dateConfig'; +import { formatDisplay } from 'common/utils/dateConfig'; import { ReactComponent as Emptyimage } from 'assets/images/empty.svg'; export default function Pip(props) { diff --git a/server/__tests__/utils/time.tests.js b/server/__tests__/utils/time.tests.js deleted file mode 100644 index 361614ff4..000000000 --- a/server/__tests__/utils/time.tests.js +++ /dev/null @@ -1,16 +0,0 @@ -import { stringFromMillis } from '../../src/utils/time'; - -const t1 = { val: null, result: '...' }; -test('test stringFromMillis() on null values', () => { - expect(stringFromMillis(t1.val)).toBe(t1.result); -}); - -const t2 = { val: 3600000, result: '01:00:00' }; -test('test stringFromMillis() on valid millis', () => { - expect(stringFromMillis(t2.val)).toBe(t2.result); -}); - -const t3 = { val: -3600000, result: '-01:00:00' }; -test('test stringFromMillis() on negative millis', () => { - expect(stringFromMillis(t3.val)).toBe(t3.result); -}); diff --git a/server/src/utils/__tests__/time.tests.js b/server/src/utils/__tests__/time.tests.js new file mode 100644 index 000000000..7f32020cf --- /dev/null +++ b/server/src/utils/__tests__/time.tests.js @@ -0,0 +1,58 @@ +import { stringFromMillis } from '../time.js'; + +describe('test string to milis function', () => { + it('test with null values', () => { + const t = { val: null, result: '...' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with valid millis', () => { + const t = { val: 3600000, result: '01:00:00' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with negative millis', () => { + const t = { val: -3600000, result: '-01:00:00' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with -1', () => { + const t = { val: -1, result: '-00:00:00' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with 0', () => { + const t = { val: 0, result: '00:00:00' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with -0', () => { + const t = { val: -0, result: '00:00:00' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with 999', () => { + const t = { val: 999, result: '00:00:00' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with 1000', () => { + const t = { val: 1000, result: '00:00:01' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with 86400000 (24 hours)', () => { + const t = { val: 86400000, result: '00:00:00' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with 86401000 (24 hours and 1 second)', () => { + const t = { val: 86401000, result: '00:00:01' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); + + it('test with -86401000 (-24 hours and 1 second)', () => { + const t = { val: -86401000, result: '-00:00:01' }; + expect(stringFromMillis(t.val)).toBe(t.result); + }); +});