@ray-js/lamp-schedule-core 1.0.0-beta-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +565 -0
- package/lib/config/dpCodes.d.ts +27 -0
- package/lib/config/dpCodes.js +30 -0
- package/lib/config/index.d.ts +2 -0
- package/lib/config/index.js +2 -0
- package/lib/config/rhythms/defaultValue.d.ts +18 -0
- package/lib/config/rhythms/defaultValue.js +72 -0
- package/lib/config/rhythms/index.d.ts +10 -0
- package/lib/config/rhythms/index.js +35 -0
- package/lib/conflict/ConflictResolver.d.ts +2 -0
- package/lib/conflict/ConflictResolver.js +284 -0
- package/lib/conflict/__test__/ConflictResolver.test.d.ts +1 -0
- package/lib/conflict/__test__/ConflictResolver.test.js +183 -0
- package/lib/conflict/__test__/index.test.d.ts +1 -0
- package/lib/conflict/__test__/index.test.js +385 -0
- package/lib/conflict/__test__/scheduleDataManager.test.d.ts +1 -0
- package/lib/conflict/__test__/scheduleDataManager.test.js +170 -0
- package/lib/conflict/__test__/transform.test.d.ts +1 -0
- package/lib/conflict/__test__/transform.test.js +454 -0
- package/lib/conflict/__test__/updateDeviceDp.d.ts +1 -0
- package/lib/conflict/__test__/updateDeviceDp.js +114 -0
- package/lib/conflict/index.d.ts +42 -0
- package/lib/conflict/index.js +103 -0
- package/lib/conflict/scheduleDataManager.d.ts +12 -0
- package/lib/conflict/scheduleDataManager.js +79 -0
- package/lib/conflict/transform.d.ts +71 -0
- package/lib/conflict/transform.js +251 -0
- package/lib/conflict/type.d.ts +55 -0
- package/lib/conflict/type.js +17 -0
- package/lib/conflict/updateDeviceDp.d.ts +1 -0
- package/lib/conflict/updateDeviceDp.js +41 -0
- package/lib/constant/index.d.ts +5 -0
- package/lib/constant/index.js +5 -0
- package/lib/context/index.d.ts +3 -0
- package/lib/context/index.js +3 -0
- package/lib/context/rhythms/actions.d.ts +20 -0
- package/lib/context/rhythms/actions.js +52 -0
- package/lib/context/rhythms/index.d.ts +5 -0
- package/lib/context/rhythms/index.js +51 -0
- package/lib/context/rhythms/reducer.d.ts +24 -0
- package/lib/context/rhythms/reducer.js +38 -0
- package/lib/context/schedule/actions.d.ts +7 -0
- package/lib/context/schedule/actions.js +51 -0
- package/lib/context/schedule/context.d.ts +6 -0
- package/lib/context/schedule/context.js +52 -0
- package/lib/context/schedule/index.d.ts +1 -0
- package/lib/context/schedule/index.js +1 -0
- package/lib/context/schedule/reducer.d.ts +16 -0
- package/lib/context/schedule/reducer.js +104 -0
- package/lib/context/schedule/type.d.ts +41 -0
- package/lib/context/schedule/type.js +11 -0
- package/lib/context/timer/actions.d.ts +8 -0
- package/lib/context/timer/actions.js +52 -0
- package/lib/context/timer/context.d.ts +10 -0
- package/lib/context/timer/context.js +53 -0
- package/lib/context/timer/index.d.ts +1 -0
- package/lib/context/timer/index.js +1 -0
- package/lib/context/timer/reducer.d.ts +15 -0
- package/lib/context/timer/reducer.js +70 -0
- package/lib/context/timer/type.d.ts +46 -0
- package/lib/context/timer/type.js +24 -0
- package/lib/dpParser/README.md +63 -0
- package/lib/dpParser/__test__/cycle.test.d.ts +1 -0
- package/lib/dpParser/__test__/cycle.test.js +258 -0
- package/lib/dpParser/__test__/random.test.d.ts +1 -0
- package/lib/dpParser/__test__/random.test.js +211 -0
- package/lib/dpParser/__test__/rhythms.test.d.ts +1 -0
- package/lib/dpParser/__test__/rhythms.test.js +71 -0
- package/lib/dpParser/__test__/rtcTimer.test.d.ts +1 -0
- package/lib/dpParser/__test__/rtcTimer.test.js +235 -0
- package/lib/dpParser/__test__/sleep.test.d.ts +1 -0
- package/lib/dpParser/__test__/sleep.test.js +71 -0
- package/lib/dpParser/__test__/sleepCommon.test.d.ts +1 -0
- package/lib/dpParser/__test__/sleepCommon.test.js +197 -0
- package/lib/dpParser/__test__/timerReport.test.d.ts +1 -0
- package/lib/dpParser/__test__/timerReport.test.js +100 -0
- package/lib/dpParser/__test__/wakeup.test.d.ts +1 -0
- package/lib/dpParser/__test__/wakeup.test.js +69 -0
- package/lib/dpParser/__test__/wakeupCommon.test.d.ts +1 -0
- package/lib/dpParser/__test__/wakeupCommon.test.js +131 -0
- package/lib/dpParser/cycle/index.d.ts +15 -0
- package/lib/dpParser/cycle/index.js +134 -0
- package/lib/dpParser/index.d.ts +23 -0
- package/lib/dpParser/index.js +43 -0
- package/lib/dpParser/random/index.d.ts +15 -0
- package/lib/dpParser/random/index.js +127 -0
- package/lib/dpParser/rhythms.d.ts +41 -0
- package/lib/dpParser/rhythms.js +116 -0
- package/lib/dpParser/rtcTimer.d.ts +17 -0
- package/lib/dpParser/rtcTimer.js +300 -0
- package/lib/dpParser/sleep/index.d.ts +9 -0
- package/lib/dpParser/sleep/index.js +29 -0
- package/lib/dpParser/sleep/sleepCommon.d.ts +11 -0
- package/lib/dpParser/sleep/sleepCommon.js +117 -0
- package/lib/dpParser/sleep/sleepSigmesh.d.ts +0 -0
- package/lib/dpParser/sleep/sleepSigmesh.js +101 -0
- package/lib/dpParser/timerReport.d.ts +11 -0
- package/lib/dpParser/timerReport.js +43 -0
- package/lib/dpParser/utils.d.ts +27 -0
- package/lib/dpParser/utils.js +53 -0
- package/lib/dpParser/wakeup/index.d.ts +10 -0
- package/lib/dpParser/wakeup/index.js +34 -0
- package/lib/dpParser/wakeup/wakeupCommon.d.ts +11 -0
- package/lib/dpParser/wakeup/wakeupCommon.js +106 -0
- package/lib/dpParser/wakeup/wakeupSigmesh.d.ts +15 -0
- package/lib/dpParser/wakeup/wakeupSigmesh.js +86 -0
- package/lib/hooks/__test__/useCommon.test.d.ts +1 -0
- package/lib/hooks/__test__/useCommon.test.js +72 -0
- package/lib/hooks/__test__/useCountdownDp.test.d.ts +1 -0
- package/lib/hooks/__test__/useCountdownDp.test.js +82 -0
- package/lib/hooks/__test__/useCycleDp.test.d.ts +1 -0
- package/lib/hooks/__test__/useCycleDp.test.js +92 -0
- package/lib/hooks/__test__/useRandomDp.test.d.ts +1 -0
- package/lib/hooks/__test__/useRandomDp.test.js +88 -0
- package/lib/hooks/__test__/useRhythmsDp.test.d.ts +1 -0
- package/lib/hooks/__test__/useRhythmsDp.test.js +81 -0
- package/lib/hooks/__test__/useSleepDp.test.d.ts +1 -0
- package/lib/hooks/__test__/useSleepDp.test.js +127 -0
- package/lib/hooks/__test__/useTimeFlush.test.d.ts +1 -0
- package/lib/hooks/__test__/useTimeFlush.test.js +109 -0
- package/lib/hooks/__test__/useTimerDp.test.d.ts +1 -0
- package/lib/hooks/__test__/useTimerDp.test.js +79 -0
- package/lib/hooks/__test__/useTimerOperate.test.d.ts +1 -0
- package/lib/hooks/__test__/useTimerOperate.test.js +286 -0
- package/lib/hooks/__test__/useTimerOperateCloud.test.d.ts +1 -0
- package/lib/hooks/__test__/useTimerOperateCloud.test.js +190 -0
- package/lib/hooks/__test__/useTimerOperateLocal.test.d.ts +1 -0
- package/lib/hooks/__test__/useTimerOperateLocal.test.js +216 -0
- package/lib/hooks/__test__/useTimerReportDp.test.d.ts +1 -0
- package/lib/hooks/__test__/useTimerReportDp.test.js +93 -0
- package/lib/hooks/__test__/useTimerSupport.test.d.ts +1 -0
- package/lib/hooks/__test__/useTimerSupport.test.js +110 -0
- package/lib/hooks/__test__/useWakeUpDp.test.d.ts +1 -0
- package/lib/hooks/__test__/useWakeUpDp.test.js +129 -0
- package/lib/hooks/useBaseLightDp.d.ts +21 -0
- package/lib/hooks/useBaseLightDp.js +165 -0
- package/lib/hooks/useCommon.d.ts +29 -0
- package/lib/hooks/useCommon.js +59 -0
- package/lib/hooks/useCommonSupport.d.ts +25 -0
- package/lib/hooks/useCommonSupport.js +241 -0
- package/lib/hooks/useCountdownDp.d.ts +13 -0
- package/lib/hooks/useCountdownDp.js +28 -0
- package/lib/hooks/useCountdownSupport.d.ts +9 -0
- package/lib/hooks/useCountdownSupport.js +13 -0
- package/lib/hooks/useCycleDp.d.ts +7 -0
- package/lib/hooks/useCycleDp.js +21 -0
- package/lib/hooks/useCycleSupport.d.ts +12 -0
- package/lib/hooks/useCycleSupport.js +16 -0
- package/lib/hooks/useRandomDp.d.ts +7 -0
- package/lib/hooks/useRandomDp.js +21 -0
- package/lib/hooks/useRandomSupport.d.ts +12 -0
- package/lib/hooks/useRandomSupport.js +16 -0
- package/lib/hooks/useRhythmsDp.d.ts +7 -0
- package/lib/hooks/useRhythmsDp.js +23 -0
- package/lib/hooks/useSleepDp.d.ts +6 -0
- package/lib/hooks/useSleepDp.js +21 -0
- package/lib/hooks/useSleepSupport.d.ts +8 -0
- package/lib/hooks/useSleepSupport.js +13 -0
- package/lib/hooks/useTimeFlush.d.ts +8 -0
- package/lib/hooks/useTimeFlush.js +31 -0
- package/lib/hooks/useTimerDp.d.ts +5 -0
- package/lib/hooks/useTimerDp.js +25 -0
- package/lib/hooks/useTimerFlushList.d.ts +11 -0
- package/lib/hooks/useTimerFlushList.js +53 -0
- package/lib/hooks/useTimerOperate.d.ts +68 -0
- package/lib/hooks/useTimerOperate.js +403 -0
- package/lib/hooks/useTimerOperateCloud.d.ts +31 -0
- package/lib/hooks/useTimerOperateCloud.js +233 -0
- package/lib/hooks/useTimerOperateLocal.d.ts +40 -0
- package/lib/hooks/useTimerOperateLocal.js +310 -0
- package/lib/hooks/useTimerReportDp.d.ts +15 -0
- package/lib/hooks/useTimerReportDp.js +48 -0
- package/lib/hooks/useTimerSupport.d.ts +13 -0
- package/lib/hooks/useTimerSupport.js +38 -0
- package/lib/hooks/useWakeUpDp.d.ts +6 -0
- package/lib/hooks/useWakeUpDp.js +21 -0
- package/lib/hooks/useWakeUpSupport.d.ts +8 -0
- package/lib/hooks/useWakeUpSupport.js +13 -0
- package/lib/hooks/useWakeupDp.d.ts +6 -0
- package/lib/hooks/useWakeupDp.js +21 -0
- package/lib/hooks/useWakeupSupport.d.ts +8 -0
- package/lib/hooks/useWakeupSupport.js +13 -0
- package/lib/i18n/index.d.ts +142 -0
- package/lib/i18n/index.js +7 -0
- package/lib/i18n/rhythms.d.ts +73 -0
- package/lib/i18n/rhythms.js +72 -0
- package/lib/i18n/strings.d.ts +73 -0
- package/lib/i18n/strings.js +6 -0
- package/lib/index.d.ts +51 -0
- package/lib/index.js +64 -0
- package/lib/types/countdown.d.ts +3 -0
- package/lib/types/countdown.js +1 -0
- package/lib/types/cycle.d.ts +22 -0
- package/lib/types/cycle.js +1 -0
- package/lib/types/global.d.ts +9 -0
- package/lib/types/index.d.ts +331 -0
- package/lib/types/index.js +76 -0
- package/lib/types/random.d.ts +20 -0
- package/lib/types/random.js +1 -0
- package/lib/types/rhythms.d.ts +79 -0
- package/lib/types/rhythms.js +15 -0
- package/lib/types/sleep.d.ts +36 -0
- package/lib/types/sleep.js +1 -0
- package/lib/types/timer.d.ts +107 -0
- package/lib/types/timer.js +1 -0
- package/lib/types/wakeup.d.ts +38 -0
- package/lib/types/wakeup.js +1 -0
- package/lib/utils/ScheduleCache.d.ts +19 -0
- package/lib/utils/ScheduleCache.js +39 -0
- package/lib/utils/ScheduleCloudProperty.d.ts +75 -0
- package/lib/utils/ScheduleCloudProperty.js +220 -0
- package/lib/utils/ScheduleDataSync.d.ts +82 -0
- package/lib/utils/ScheduleDataSync.js +127 -0
- package/lib/utils/ScheduleEmit.d.ts +67 -0
- package/lib/utils/ScheduleEmit.js +61 -0
- package/lib/utils/ScheduleLogger.d.ts +19 -0
- package/lib/utils/ScheduleLogger.js +71 -0
- package/lib/utils/ScheduleSupport.d.ts +131 -0
- package/lib/utils/ScheduleSupport.js +373 -0
- package/lib/utils/ScheduleUtils.d.ts +12 -0
- package/lib/utils/ScheduleUtils.js +51 -0
- package/lib/utils/__test__/ScheduleCloudProperty.test.d.ts +1 -0
- package/lib/utils/__test__/ScheduleCloudProperty.test.js +320 -0
- package/lib/utils/__test__/ScheduleSupport.test.d.ts +1 -0
- package/lib/utils/__test__/ScheduleSupport.test.js +211 -0
- package/lib/utils/__test__/ScheduleUtils.test.d.ts +1 -0
- package/lib/utils/__test__/ScheduleUtils.test.js +119 -0
- package/lib/utils/__test__/common.test.d.ts +1 -0
- package/lib/utils/__test__/common.test.js +147 -0
- package/lib/utils/__test__/storage.test.d.ts +1 -0
- package/lib/utils/__test__/storage.test.js +98 -0
- package/lib/utils/__test__/time.test.d.ts +1 -0
- package/lib/utils/__test__/time.test.js +146 -0
- package/lib/utils/common.d.ts +23 -0
- package/lib/utils/common.js +109 -0
- package/lib/utils/dpState.d.ts +5 -0
- package/lib/utils/dpState.js +27 -0
- package/lib/utils/getCachedSystemInfo.d.ts +39 -0
- package/lib/utils/getCachedSystemInfo.js +20 -0
- package/lib/utils/isInIDE.d.ts +1 -0
- package/lib/utils/isInIDE.js +5 -0
- package/lib/utils/storage.d.ts +5 -0
- package/lib/utils/storage.js +32 -0
- package/lib/utils/time.d.ts +40 -0
- package/lib/utils/time.js +84 -0
- package/package.json +78 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { rhythmParser } from '../rhythms';
|
|
2
|
+
// Mock ScheduleLogger
|
|
3
|
+
jest.mock('../../utils/ScheduleLogger', () => ({
|
|
4
|
+
scheduleLogger: {
|
|
5
|
+
debug: jest.fn(),
|
|
6
|
+
warn: jest.fn(),
|
|
7
|
+
error: jest.fn()
|
|
8
|
+
}
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
// Mock getSupportIns
|
|
12
|
+
const mockSupport = function () {
|
|
13
|
+
let isSigMesh = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
14
|
+
let isSupportTemp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
15
|
+
return {
|
|
16
|
+
isSigMeshDevice: () => isSigMesh,
|
|
17
|
+
isSupportDp: () => isSupportTemp
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
jest.mock('../../hooks/useCommonSupport', () => ({
|
|
21
|
+
getSupportIns: jest.fn(() => mockSupport(false, true))
|
|
22
|
+
}));
|
|
23
|
+
describe('RhythmParser', () => {
|
|
24
|
+
describe('parser', () => {
|
|
25
|
+
it('should return default data for empty DP string', () => {
|
|
26
|
+
const result = rhythmParser.parser('');
|
|
27
|
+
expect(result).toHaveProperty('version', 0);
|
|
28
|
+
expect(result).toHaveProperty('power', false);
|
|
29
|
+
expect(result).toHaveProperty('mode', 0);
|
|
30
|
+
expect(result).toHaveProperty('weeks');
|
|
31
|
+
expect(result).toHaveProperty('number');
|
|
32
|
+
expect(result).toHaveProperty('rhythms');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('formatter', () => {
|
|
36
|
+
it('should return empty string if data is null', () => {
|
|
37
|
+
const result = rhythmParser.formatter(null);
|
|
38
|
+
expect(result).toBe('');
|
|
39
|
+
});
|
|
40
|
+
it('should format a valid TRhythmData object', () => {
|
|
41
|
+
const result = rhythmParser.formatter({
|
|
42
|
+
version: 0,
|
|
43
|
+
power: true,
|
|
44
|
+
mode: 1,
|
|
45
|
+
weeks: [1, 0, 1, 0, 1, 0, 1, 0],
|
|
46
|
+
number: 2,
|
|
47
|
+
rhythms: [{
|
|
48
|
+
power: true,
|
|
49
|
+
hour: 6,
|
|
50
|
+
minute: 0,
|
|
51
|
+
hue: 10,
|
|
52
|
+
saturation: 20,
|
|
53
|
+
value: 30,
|
|
54
|
+
brightness: 40,
|
|
55
|
+
temperature: 50
|
|
56
|
+
}, {
|
|
57
|
+
power: false,
|
|
58
|
+
hour: 7,
|
|
59
|
+
minute: 30,
|
|
60
|
+
hue: 11,
|
|
61
|
+
saturation: 21,
|
|
62
|
+
value: 31,
|
|
63
|
+
brightness: 41,
|
|
64
|
+
temperature: 51
|
|
65
|
+
}]
|
|
66
|
+
});
|
|
67
|
+
expect(typeof result).toBe('string');
|
|
68
|
+
expect(result.length).toBeGreaterThan(0);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
2
|
+
import { RtcTimerFormatter, rtcTimerParser } from '../rtcTimer';
|
|
3
|
+
jest.mock('../../utils/isInIDE', () => ({
|
|
4
|
+
isInIDEFun: jest.fn().mockReturnValue(false)
|
|
5
|
+
}));
|
|
6
|
+
const DEFAULT_RTC_TIMER_VALUE = {
|
|
7
|
+
timerId: '1',
|
|
8
|
+
status: false,
|
|
9
|
+
loops: '1111111',
|
|
10
|
+
time: '08:30',
|
|
11
|
+
dps: {
|
|
12
|
+
switch_led: false
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Helper to convert HH:mm to minutes
|
|
17
|
+
const timeToMinute = timeStr => {
|
|
18
|
+
const [hour, min] = timeStr.split(':').map(Number);
|
|
19
|
+
return hour * 60 + min;
|
|
20
|
+
};
|
|
21
|
+
describe('RtcTimerFormatter', () => {
|
|
22
|
+
let formatterInstance;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
formatterInstance = new RtcTimerFormatter();
|
|
25
|
+
jest.clearAllMocks();
|
|
26
|
+
});
|
|
27
|
+
describe('parser', () => {
|
|
28
|
+
it('should return default value for empty string', () => {
|
|
29
|
+
expect(formatterInstance.parser('')).toEqual(DEFAULT_RTC_TIMER_VALUE);
|
|
30
|
+
});
|
|
31
|
+
it('should return default value for invalid length string', () => {
|
|
32
|
+
expect(formatterInstance.parser('0102030405')).toEqual(DEFAULT_RTC_TIMER_VALUE);
|
|
33
|
+
});
|
|
34
|
+
it('should parse a delete timer DP string (4 chars)', () => {
|
|
35
|
+
// ID: 82 (status=true, timerId=2)
|
|
36
|
+
// Minimal delete command, assuming 00 is padding or ignored by parser for delete
|
|
37
|
+
|
|
38
|
+
expect(formatterInstance.parser('8200')).toEqual({
|
|
39
|
+
timerId: '2',
|
|
40
|
+
status: true
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
it('should parse a power (switch_led) timer DP string (14 chars)', () => {
|
|
44
|
+
// ID: 81 (status=true, timerId=1)
|
|
45
|
+
// timer_type: 01
|
|
46
|
+
// loops: 7f (all days)
|
|
47
|
+
// startTimeType: 00
|
|
48
|
+
// time: 0384 (900 mins -> 15:00)
|
|
49
|
+
// deviceAction: 00 (off) or 01 (on)
|
|
50
|
+
|
|
51
|
+
expect(formatterInstance.parser('81017f00038401')).toEqual({
|
|
52
|
+
timerId: '1',
|
|
53
|
+
status: true,
|
|
54
|
+
loops: '1111111',
|
|
55
|
+
time: '15:00',
|
|
56
|
+
dps: {
|
|
57
|
+
switch_led: false
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
it('should parse a bright light timer DP string (18 chars)', () => {
|
|
62
|
+
// ID: 82 (status=true, timerId=2)
|
|
63
|
+
// timer_type: 01, loops: 40 (Sat), startTimeType: 00, time: 012C (300 mins -> 05:00)
|
|
64
|
+
// deviceAction: 02 (white light)
|
|
65
|
+
// bright_value: 64 (100), temp_value: 32 (50)
|
|
66
|
+
|
|
67
|
+
expect(formatterInstance.parser('82014000012C026432')).toEqual({
|
|
68
|
+
timerId: '2',
|
|
69
|
+
status: true,
|
|
70
|
+
loops: '0000001',
|
|
71
|
+
// Saturday
|
|
72
|
+
time: '05:00',
|
|
73
|
+
dps: {
|
|
74
|
+
bright_value: 100,
|
|
75
|
+
temp_value: 50
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
it('should parse a colour light timer DP string (22 chars)', () => {
|
|
80
|
+
// ID: 83 (status=true, timerId=3)
|
|
81
|
+
// timer_type: 01, loops: 01 (Sun), startTimeType: 00, time: 04B0 (1200 mins -> 20:00)
|
|
82
|
+
// deviceAction: 03 (colour light)
|
|
83
|
+
// hue: 0078 (120), saturation: 64 (100), value: 32 (50)
|
|
84
|
+
|
|
85
|
+
expect(formatterInstance.parser('8301010004B00300786432')).toEqual({
|
|
86
|
+
timerId: '3',
|
|
87
|
+
status: true,
|
|
88
|
+
loops: '1000000',
|
|
89
|
+
// Sunday
|
|
90
|
+
time: '20:00',
|
|
91
|
+
dps: {
|
|
92
|
+
colour_data: {
|
|
93
|
+
hue: 120,
|
|
94
|
+
saturation: 100,
|
|
95
|
+
value: 50
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
it('should parse a mix light timer DP string (26 chars)', () => {
|
|
101
|
+
// ID: 84 (status=true, timerId=4)
|
|
102
|
+
// timer_type: 01, loops: 02 (Mon), startTimeType: 00, time: 0064 (100 mins -> 01:40)
|
|
103
|
+
// deviceAction: 04 (mix light)
|
|
104
|
+
// hue: 00F0 (240), sat: 50 (80), val: 1E (30)
|
|
105
|
+
// bright_value: 4B (75), temp_value: 28 (40)
|
|
106
|
+
|
|
107
|
+
expect(formatterInstance.parser('8401020000640400F0501E4B28')).toEqual({
|
|
108
|
+
timerId: '4',
|
|
109
|
+
status: true,
|
|
110
|
+
loops: '0100000',
|
|
111
|
+
// Monday
|
|
112
|
+
time: '01:40',
|
|
113
|
+
dps: {
|
|
114
|
+
colour_data: {
|
|
115
|
+
hue: 240,
|
|
116
|
+
saturation: 80,
|
|
117
|
+
value: 30
|
|
118
|
+
},
|
|
119
|
+
bright_value: 75,
|
|
120
|
+
temp_value: 40
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe('formatter', () => {
|
|
126
|
+
it('should format a power (switch_led) timer to DP string', () => {
|
|
127
|
+
// id: 81 (status=1, id=1)
|
|
128
|
+
// timer_type: 01 (fixed in formatter)
|
|
129
|
+
// loops: 7f (1111111)
|
|
130
|
+
// startTimeType: 00 (fixed in formatter)
|
|
131
|
+
// time: 0384 (900 mins)
|
|
132
|
+
// deviceAction: 01 (from dps.switch_led = true)
|
|
133
|
+
|
|
134
|
+
expect(formatterInstance.formatter({
|
|
135
|
+
timerId: '1',
|
|
136
|
+
status: true,
|
|
137
|
+
loops: '1111111',
|
|
138
|
+
time: '15:00',
|
|
139
|
+
dps: {
|
|
140
|
+
switch_led: true
|
|
141
|
+
}
|
|
142
|
+
})).toBe('81017f00038401');
|
|
143
|
+
});
|
|
144
|
+
it('should format a bright light timer to DP string', () => {
|
|
145
|
+
// id: 82, type:01, loops:40, startTimeType:00, time:012c
|
|
146
|
+
// deviceAction: 02
|
|
147
|
+
// bright:64, temp:32
|
|
148
|
+
|
|
149
|
+
expect(formatterInstance.formatter({
|
|
150
|
+
timerId: '2',
|
|
151
|
+
status: true,
|
|
152
|
+
loops: '0000001',
|
|
153
|
+
// Sat
|
|
154
|
+
time: '05:00',
|
|
155
|
+
dps: {
|
|
156
|
+
bright_value: 100,
|
|
157
|
+
temp_value: 50
|
|
158
|
+
}
|
|
159
|
+
})).toBe('82014000012c026432');
|
|
160
|
+
});
|
|
161
|
+
it('should format a colour light timer to DP string', () => {
|
|
162
|
+
// id: 83, type:01, loops:01, startTimeType:00, time:04b0
|
|
163
|
+
// deviceAction: 03
|
|
164
|
+
// hue:0078, sat:64, val:32
|
|
165
|
+
|
|
166
|
+
expect(formatterInstance.formatter({
|
|
167
|
+
timerId: '3',
|
|
168
|
+
status: true,
|
|
169
|
+
loops: '1000000',
|
|
170
|
+
// Sun
|
|
171
|
+
time: '20:00',
|
|
172
|
+
dps: {
|
|
173
|
+
colour_data: {
|
|
174
|
+
hue: 120,
|
|
175
|
+
saturation: 100,
|
|
176
|
+
value: 50
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
})).toBe('8301010004b00300786432');
|
|
180
|
+
});
|
|
181
|
+
it('should format a mix light timer to DP string', () => {
|
|
182
|
+
// id: 84, type:01, loops:02, startTimeType:00, time:0064
|
|
183
|
+
// deviceAction: 04
|
|
184
|
+
// hue:00f0, sat:50, val:1e, bright:4b, temp:28
|
|
185
|
+
|
|
186
|
+
expect(formatterInstance.formatter({
|
|
187
|
+
timerId: '4',
|
|
188
|
+
status: true,
|
|
189
|
+
loops: '0100000',
|
|
190
|
+
// Mon
|
|
191
|
+
time: '01:40',
|
|
192
|
+
dps: {
|
|
193
|
+
colour_data: {
|
|
194
|
+
hue: 240,
|
|
195
|
+
saturation: 80,
|
|
196
|
+
value: 30
|
|
197
|
+
},
|
|
198
|
+
bright_value: 75,
|
|
199
|
+
temp_value: 40
|
|
200
|
+
}
|
|
201
|
+
})).toBe('8401020000640400f0501e4b28');
|
|
202
|
+
});
|
|
203
|
+
it('should format a timer to be deleted (status=false, no dps, specific id)', () => {
|
|
204
|
+
// The formatter is designed to create full timer strings.
|
|
205
|
+
// To delete a timer, one typically sends a short command with just ID and status=false.
|
|
206
|
+
// However, the formatter will construct a full string. If the intention is to format a delete *command*,
|
|
207
|
+
// the formatter logic would need to be different. This tests formatting a timer that is 'off'.
|
|
208
|
+
|
|
209
|
+
// id: 05 (status=0, id=5)
|
|
210
|
+
// type:01, loops:00, startTimeType:00, time:0000
|
|
211
|
+
// deviceAction: 00 (from dps.switch_led = false)
|
|
212
|
+
|
|
213
|
+
expect(formatterInstance.formatter({
|
|
214
|
+
timerId: '5',
|
|
215
|
+
status: false,
|
|
216
|
+
// This status is part of the ID byte
|
|
217
|
+
loops: '0000000',
|
|
218
|
+
// No repeat
|
|
219
|
+
time: '00:00',
|
|
220
|
+
dps: {
|
|
221
|
+
switch_led: false
|
|
222
|
+
} // Default dps for an 'off' timer
|
|
223
|
+
})).toBe('05010000000000');
|
|
224
|
+
});
|
|
225
|
+
it('should handle string input by returning it directly', () => {
|
|
226
|
+
const dpString = 'alreadyFormattedString';
|
|
227
|
+
expect(formatterInstance.formatter(dpString)).toBe(dpString);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
describe('rtcTimerParser instance', () => {
|
|
231
|
+
it('should be an instance of RtcTimerFormatter', () => {
|
|
232
|
+
expect(rtcTimerParser).toBeInstanceOf(RtcTimerFormatter);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { SleepParser } from '../sleep';
|
|
2
|
+
describe('SleepParser', () => {
|
|
3
|
+
const parser = new SleepParser();
|
|
4
|
+
it('should return default value when parsing empty string', () => {
|
|
5
|
+
const result = parser.parser('');
|
|
6
|
+
expect(result).toEqual({
|
|
7
|
+
version: 0,
|
|
8
|
+
length: 0,
|
|
9
|
+
nodes: []
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
it('should format default value correctly', () => {
|
|
13
|
+
const result = parser.formatter({
|
|
14
|
+
version: 0,
|
|
15
|
+
length: 0,
|
|
16
|
+
nodes: []
|
|
17
|
+
});
|
|
18
|
+
// 根据 sleepCommon.ts 的 formatter 逻辑,空数据会返回 '0000'
|
|
19
|
+
expect(result).toBe('0000');
|
|
20
|
+
});
|
|
21
|
+
it('should parse a valid dpStr and format it back', () => {
|
|
22
|
+
const dpStr = '0101017f01010a010a0b0c0d0e';
|
|
23
|
+
const expectedParsedData = {
|
|
24
|
+
version: 1,
|
|
25
|
+
length: 1,
|
|
26
|
+
nodes: [{
|
|
27
|
+
onOff: true,
|
|
28
|
+
loops: '1111111',
|
|
29
|
+
step: 1,
|
|
30
|
+
hour: 1,
|
|
31
|
+
minute: 10,
|
|
32
|
+
hue: 110,
|
|
33
|
+
saturation: 11,
|
|
34
|
+
value: 12,
|
|
35
|
+
brightness: 13,
|
|
36
|
+
temperature: 14,
|
|
37
|
+
index: 0
|
|
38
|
+
}]
|
|
39
|
+
};
|
|
40
|
+
const parsedResult = parser.parser(dpStr);
|
|
41
|
+
expect(parsedResult).toEqual(expectedParsedData);
|
|
42
|
+
const formattedResult = parser.formatter(expectedParsedData);
|
|
43
|
+
expect(formattedResult.toLowerCase()).toBe(dpStr.toLowerCase());
|
|
44
|
+
});
|
|
45
|
+
it('should handle dpStr with invalid length', () => {
|
|
46
|
+
// 少两位
|
|
47
|
+
const result = parser.parser('00010102010a1e0078325000');
|
|
48
|
+
expect(result).toEqual({
|
|
49
|
+
version: 0,
|
|
50
|
+
length: 0,
|
|
51
|
+
nodes: []
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
it('should handle dpStr with more than 4 nodes by taking only first 4', () => {
|
|
55
|
+
// 假设 dpStr 代表5个节点,但length字段为4
|
|
56
|
+
|
|
57
|
+
// node 5 (this one should be ignored by parser if length is 4)
|
|
58
|
+
const result = parser.parser('0004' +
|
|
59
|
+
// version 0, length 4
|
|
60
|
+
'0102010a1e007832500000' +
|
|
61
|
+
// node 1
|
|
62
|
+
'0104020b2800641e320000' +
|
|
63
|
+
// node 2
|
|
64
|
+
'0008030c3c00500a190000' +
|
|
65
|
+
// node 3
|
|
66
|
+
'0110040d46003c000f0000' +
|
|
67
|
+
// node 4
|
|
68
|
+
'0120050e500028640a0000');
|
|
69
|
+
expect(result.nodes.length).toBe(4);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { Sleep, sleepParser } from '../sleep/sleepCommon';
|
|
2
|
+
const DEFAULT_EMPTY_SLEEP_DATA = {
|
|
3
|
+
version: 0,
|
|
4
|
+
length: 0,
|
|
5
|
+
nodes: []
|
|
6
|
+
};
|
|
7
|
+
describe('Sleep (Common)', () => {
|
|
8
|
+
let sleepInstance;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
sleepInstance = new Sleep();
|
|
11
|
+
jest.clearAllMocks();
|
|
12
|
+
});
|
|
13
|
+
describe('parser', () => {
|
|
14
|
+
it('should parse a valid DP string into TSleepData', () => {
|
|
15
|
+
// version=00, length=01 (1 node)
|
|
16
|
+
// Node 1: onOff=01 (true), loops=42 (Sat, Sun - 01000010 -> reverse 01000010), step=01
|
|
17
|
+
// hour=0b (11), minute=15 (21)
|
|
18
|
+
// hueHundreds=00, hueTensOnes=00 (hue=0)
|
|
19
|
+
// sat=00, val=00, bright=00, temp=00
|
|
20
|
+
const dpValue = '00 01 01 42 01 0b 15 00 00 00 00 00 00'.replaceAll(' ', ''); // 2 + 2 + 22 = 26 bytes = 52 chars
|
|
21
|
+
|
|
22
|
+
expect(sleepInstance.parser(dpValue)).toEqual({
|
|
23
|
+
version: 0,
|
|
24
|
+
length: 1,
|
|
25
|
+
nodes: [{
|
|
26
|
+
onOff: true,
|
|
27
|
+
loops: '0100001',
|
|
28
|
+
step: 1,
|
|
29
|
+
hour: 11,
|
|
30
|
+
minute: 21,
|
|
31
|
+
hue: 0,
|
|
32
|
+
saturation: 0,
|
|
33
|
+
value: 0,
|
|
34
|
+
brightness: 0,
|
|
35
|
+
temperature: 0,
|
|
36
|
+
index: 0
|
|
37
|
+
}]
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
it('should parse a DP string with multiple nodes', () => {
|
|
41
|
+
// version=0, length=2
|
|
42
|
+
// Node 1: onOff=true, loops=Mon(00000100->04), step=1, time=10:30, color(120,100,50,80,60)
|
|
43
|
+
// Node 2: onOff=false, loops=Tue(00001000->08), step=2, time=12:00, color(0,0,0,0,0)
|
|
44
|
+
|
|
45
|
+
// Node 2
|
|
46
|
+
|
|
47
|
+
expect(sleepInstance.parser('0002' +
|
|
48
|
+
// version, length
|
|
49
|
+
'0104010a1e01146432503c' +
|
|
50
|
+
// Node 1
|
|
51
|
+
'0008020c00000000000000')).toEqual({
|
|
52
|
+
version: 0,
|
|
53
|
+
length: 2,
|
|
54
|
+
nodes: [{
|
|
55
|
+
onOff: true,
|
|
56
|
+
loops: '0010000',
|
|
57
|
+
step: 1,
|
|
58
|
+
hour: 10,
|
|
59
|
+
minute: 30,
|
|
60
|
+
hue: 120,
|
|
61
|
+
saturation: 100,
|
|
62
|
+
value: 50,
|
|
63
|
+
brightness: 80,
|
|
64
|
+
temperature: 60,
|
|
65
|
+
index: 0
|
|
66
|
+
}, {
|
|
67
|
+
onOff: false,
|
|
68
|
+
loops: '0001000',
|
|
69
|
+
step: 2,
|
|
70
|
+
hour: 12,
|
|
71
|
+
minute: 0,
|
|
72
|
+
hue: 0,
|
|
73
|
+
saturation: 0,
|
|
74
|
+
value: 0,
|
|
75
|
+
brightness: 0,
|
|
76
|
+
temperature: 0,
|
|
77
|
+
index: 1
|
|
78
|
+
}]
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
it('should return default data for empty DP string', () => {
|
|
82
|
+
expect(sleepInstance.parser('')).toEqual(DEFAULT_EMPTY_SLEEP_DATA);
|
|
83
|
+
});
|
|
84
|
+
it('should return default data for invalid DP string length', () => {
|
|
85
|
+
// Missing last few bytes
|
|
86
|
+
expect(sleepInstance.parser('00010142010b1500000000')).toEqual(DEFAULT_EMPTY_SLEEP_DATA);
|
|
87
|
+
});
|
|
88
|
+
it('should handle hue rounding', () => {
|
|
89
|
+
// hueHundreds=0001, hueTensOnes=0015 (hue=121)
|
|
90
|
+
|
|
91
|
+
const result = sleepInstance.parser('00010101010101011500000000');
|
|
92
|
+
expect(result.nodes[0].hue).toBe(121);
|
|
93
|
+
});
|
|
94
|
+
it('should cap length at 4 nodes', () => {
|
|
95
|
+
// version=0, length=5 (will be capped at 4)
|
|
96
|
+
|
|
97
|
+
// Node 5 (ignored)
|
|
98
|
+
|
|
99
|
+
const result = sleepInstance.parser('0005' +
|
|
100
|
+
// version, length (will be capped to 4)
|
|
101
|
+
'0104010a1e01146432503c' +
|
|
102
|
+
// Node 1
|
|
103
|
+
'0008020c00000000000000' +
|
|
104
|
+
// Node 2
|
|
105
|
+
'0000000000000000000000' +
|
|
106
|
+
// Node 3
|
|
107
|
+
'0000000000000000000000' +
|
|
108
|
+
// Node 4
|
|
109
|
+
'0000000000000000000000');
|
|
110
|
+
expect(result.length).toBe(4);
|
|
111
|
+
expect(result.nodes.length).toBe(4);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
describe('formatter', () => {
|
|
115
|
+
it('should format TSleepData into a DP string', () => {
|
|
116
|
+
expect(sleepInstance.formatter({
|
|
117
|
+
version: 0,
|
|
118
|
+
length: 1,
|
|
119
|
+
nodes: [{
|
|
120
|
+
onOff: true,
|
|
121
|
+
loops: '0100001',
|
|
122
|
+
step: 1,
|
|
123
|
+
hour: 11,
|
|
124
|
+
minute: 21,
|
|
125
|
+
hue: 0,
|
|
126
|
+
saturation: 0,
|
|
127
|
+
value: 0,
|
|
128
|
+
brightness: 0,
|
|
129
|
+
temperature: 0,
|
|
130
|
+
index: 0
|
|
131
|
+
}]
|
|
132
|
+
})).toBe('00010142010b15000000000000');
|
|
133
|
+
});
|
|
134
|
+
it('should format TSleepData with multiple nodes', () => {
|
|
135
|
+
expect(sleepInstance.formatter({
|
|
136
|
+
version: 0,
|
|
137
|
+
length: 2,
|
|
138
|
+
nodes: [{
|
|
139
|
+
onOff: true,
|
|
140
|
+
loops: '0010000',
|
|
141
|
+
step: 1,
|
|
142
|
+
hour: 10,
|
|
143
|
+
minute: 30,
|
|
144
|
+
hue: 120,
|
|
145
|
+
saturation: 100,
|
|
146
|
+
value: 50,
|
|
147
|
+
brightness: 80,
|
|
148
|
+
temperature: 60,
|
|
149
|
+
index: 0
|
|
150
|
+
}, {
|
|
151
|
+
onOff: false,
|
|
152
|
+
loops: '0001000',
|
|
153
|
+
step: 2,
|
|
154
|
+
hour: 12,
|
|
155
|
+
minute: 0,
|
|
156
|
+
hue: 0,
|
|
157
|
+
saturation: 0,
|
|
158
|
+
value: 0,
|
|
159
|
+
brightness: 0,
|
|
160
|
+
temperature: 0,
|
|
161
|
+
index: 1
|
|
162
|
+
}]
|
|
163
|
+
})).toBe('00020104010a1e01146432503c0008020c00000000000000');
|
|
164
|
+
});
|
|
165
|
+
it('should format TSleepData with empty nodes array', () => {
|
|
166
|
+
expect(sleepInstance.formatter({
|
|
167
|
+
version: 1,
|
|
168
|
+
length: 0,
|
|
169
|
+
nodes: []
|
|
170
|
+
})).toBe('0100');
|
|
171
|
+
});
|
|
172
|
+
it('should use default color values if all color props are 0', () => {
|
|
173
|
+
expect(sleepInstance.formatter({
|
|
174
|
+
version: 0,
|
|
175
|
+
length: 1,
|
|
176
|
+
nodes: [{
|
|
177
|
+
onOff: true,
|
|
178
|
+
loops: '1000000',
|
|
179
|
+
step: 1,
|
|
180
|
+
hour: 8,
|
|
181
|
+
minute: 0,
|
|
182
|
+
hue: 0,
|
|
183
|
+
saturation: 0,
|
|
184
|
+
value: 0,
|
|
185
|
+
brightness: 0,
|
|
186
|
+
temperature: 0,
|
|
187
|
+
index: 0
|
|
188
|
+
}]
|
|
189
|
+
})).toBe('00010101010800000000000000');
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
describe('sleepParser instance', () => {
|
|
193
|
+
it('should be an instance of Sleep', () => {
|
|
194
|
+
expect(sleepParser).toBeInstanceOf(Sleep);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { TimerReportFormatter, timerReportParser } from '../timerReport';
|
|
2
|
+
describe('TimerReportFormatter', () => {
|
|
3
|
+
let formatterInstance;
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
formatterInstance = new TimerReportFormatter();
|
|
6
|
+
});
|
|
7
|
+
describe('parser', () => {
|
|
8
|
+
it('should parse a valid DP string into TTimerReport array', () => {
|
|
9
|
+
// 81 -> 10000001 (status=true, id=1)
|
|
10
|
+
// 02 -> 00000010 (status=false, id=2)
|
|
11
|
+
// 8F -> 10001111 (status=true, id=15)
|
|
12
|
+
|
|
13
|
+
expect(formatterInstance.parser('81028f')).toEqual([{
|
|
14
|
+
status: true,
|
|
15
|
+
id: 1
|
|
16
|
+
}, {
|
|
17
|
+
status: false,
|
|
18
|
+
id: 2
|
|
19
|
+
}, {
|
|
20
|
+
status: true,
|
|
21
|
+
id: 15
|
|
22
|
+
}]);
|
|
23
|
+
});
|
|
24
|
+
it('should return default empty array for empty DP string', () => {
|
|
25
|
+
expect(formatterInstance.parser('')).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
it('should return default empty array for undefined DP string', () => {
|
|
28
|
+
expect(formatterInstance.parser(undefined)).toEqual([]);
|
|
29
|
+
});
|
|
30
|
+
it('should handle a DP string with a single report', () => {
|
|
31
|
+
// C3 -> 11000011 (status=true, id=67)
|
|
32
|
+
|
|
33
|
+
expect(formatterInstance.parser('c3')).toEqual([{
|
|
34
|
+
status: true,
|
|
35
|
+
id: 3
|
|
36
|
+
}]);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('formatter', () => {
|
|
40
|
+
it('should format TTimerReport array into a DP string', () => {
|
|
41
|
+
expect(formatterInstance.formatter([{
|
|
42
|
+
status: true,
|
|
43
|
+
id: 1
|
|
44
|
+
},
|
|
45
|
+
// 10000001 -> 81
|
|
46
|
+
{
|
|
47
|
+
status: false,
|
|
48
|
+
id: 2
|
|
49
|
+
},
|
|
50
|
+
// 00000010 -> 02
|
|
51
|
+
{
|
|
52
|
+
status: true,
|
|
53
|
+
id: 15
|
|
54
|
+
} // 10001111 -> 8f
|
|
55
|
+
])).toBe('81028f');
|
|
56
|
+
});
|
|
57
|
+
it('should format an empty TTimerReport array into an empty string', () => {
|
|
58
|
+
expect(formatterInstance.formatter([])).toBe('');
|
|
59
|
+
});
|
|
60
|
+
it('should handle a single task in TTimerReport array', () => {
|
|
61
|
+
// 11000011 -> c3
|
|
62
|
+
|
|
63
|
+
expect(formatterInstance.formatter([{
|
|
64
|
+
status: true,
|
|
65
|
+
id: 67
|
|
66
|
+
}])).toBe('c3');
|
|
67
|
+
});
|
|
68
|
+
it('should handle id 0', () => {
|
|
69
|
+
// 10000000 -> 80
|
|
70
|
+
|
|
71
|
+
expect(formatterInstance.formatter([{
|
|
72
|
+
status: true,
|
|
73
|
+
id: 0
|
|
74
|
+
}])).toBe('80');
|
|
75
|
+
});
|
|
76
|
+
it('should handle max id (127)', () => {
|
|
77
|
+
// 01111111 -> 7f
|
|
78
|
+
|
|
79
|
+
expect(formatterInstance.formatter([{
|
|
80
|
+
status: false,
|
|
81
|
+
id: 127
|
|
82
|
+
}])).toBe('7f');
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('timerReportParser instance', () => {
|
|
86
|
+
it('should be an instance of TimerReportFormatter', () => {
|
|
87
|
+
// The exported timerReportParser is an instance of TimerReportFormatter.
|
|
88
|
+
// We can check if it has the parser and formatter methods.
|
|
89
|
+
expect(timerReportParser.parser).toBeInstanceOf(Function);
|
|
90
|
+
expect(timerReportParser.formatter).toBeInstanceOf(Function);
|
|
91
|
+
|
|
92
|
+
// To be more precise, we can check if the constructor name matches,
|
|
93
|
+
// though this can be brittle if the class is wrapped or transpiled differently.
|
|
94
|
+
// expect(timerReportParser.constructor.name).toBe('TimerReportFormatter');
|
|
95
|
+
// Or, more robustly, check if it behaves like an instance:
|
|
96
|
+
const testInstance = new TimerReportFormatter();
|
|
97
|
+
expect(Object.getPrototypeOf(timerReportParser)).toBe(Object.getPrototypeOf(testInstance));
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|