9 func TestParseSleep(t *testing.T) {
10 ctx := context.Background()
12 input := `{"sleep":[{"dateOfSleep":"2018-02-04","duration":30420000,"efficiency":95,"endTime":"2018-02-04T06:36:30.000","infoCode":0,"isMainSleep":true,"levels":{"data":[{"dateTime":"2018-02-03T22:09:30.000","level":"light","seconds":390},{"dateTime":"2018-02-03T22:16:00.000","level":"wake","seconds":840},{"dateTime":"2018-02-03T22:30:00.000","level":"light","seconds":1110},{"dateTime":"2018-02-03T22:48:30.000","level":"wake","seconds":870},{"dateTime":"2018-02-03T23:03:00.000","level":"light","seconds":120},{"dateTime":"2018-02-03T23:05:00.000","level":"wake","seconds":600},{"dateTime":"2018-02-03T23:15:00.000","level":"light","seconds":180},{"dateTime":"2018-02-03T23:18:00.000","level":"deep","seconds":360},{"dateTime":"2018-02-03T23:24:00.000","level":"light","seconds":390},{"dateTime":"2018-02-03T23:30:30.000","level":"deep","seconds":390},{"dateTime":"2018-02-03T23:37:00.000","level":"light","seconds":2580},{"dateTime":"2018-02-04T00:20:00.000","level":"rem","seconds":1080},{"dateTime":"2018-02-04T00:38:00.000","level":"wake","seconds":480},{"dateTime":"2018-02-04T00:46:00.000","level":"light","seconds":540},{"dateTime":"2018-02-04T00:55:00.000","level":"deep","seconds":1770},{"dateTime":"2018-02-04T01:24:30.000","level":"light","seconds":390},{"dateTime":"2018-02-04T01:31:00.000","level":"wake","seconds":630},{"dateTime":"2018-02-04T01:41:30.000","level":"light","seconds":480},{"dateTime":"2018-02-04T01:49:30.000","level":"rem","seconds":930},{"dateTime":"2018-02-04T02:05:00.000","level":"light","seconds":1920},{"dateTime":"2018-02-04T02:37:00.000","level":"deep","seconds":1830},{"dateTime":"2018-02-04T03:07:30.000","level":"light","seconds":630},{"dateTime":"2018-02-04T03:18:00.000","level":"rem","seconds":1740},{"dateTime":"2018-02-04T03:47:00.000","level":"wake","seconds":960},{"dateTime":"2018-02-04T04:03:00.000","level":"light","seconds":4860},{"dateTime":"2018-02-04T05:24:00.000","level":"rem","seconds":1890},{"dateTime":"2018-02-04T05:55:30.000","level":"light","seconds":2460}],"shortData":[{"dateTime":"2018-02-03T22:10:00.000","level":"wake","seconds":120},{"dateTime":"2018-02-03T22:13:30.000","level":"wake","seconds":30},{"dateTime":"2018-02-03T22:39:00.000","level":"wake","seconds":60},{"dateTime":"2018-02-03T23:52:00.000","level":"wake","seconds":60},{"dateTime":"2018-02-03T23:56:30.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T00:04:30.000","level":"wake","seconds":90},{"dateTime":"2018-02-04T00:17:30.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T00:51:30.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T02:06:30.000","level":"wake","seconds":90},{"dateTime":"2018-02-04T02:17:00.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T02:24:00.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T03:07:00.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T03:23:30.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T03:42:00.000","level":"wake","seconds":60},{"dateTime":"2018-02-04T03:45:00.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T04:16:30.000","level":"wake","seconds":30},{"dateTime":"2018-02-04T04:21:30.000","level":"wake","seconds":60},{"dateTime":"2018-02-04T04:47:30.000","level":"wake","seconds":60},{"dateTime":"2018-02-04T06:29:00.000","level":"wake","seconds":30}],"summary":{"deep":{"count":4,"minutes":72,"thirtyDayAvgMinutes":81},"light":{"count":28,"minutes":255,"thirtyDayAvgMinutes":272},"rem":{"count":7,"minutes":92,"thirtyDayAvgMinutes":90},"wake":{"count":25,"minutes":88,"thirtyDayAvgMinutes":81}}},"logId":17122464961,"minutesAfterWakeup":0,"minutesAsleep":419,"minutesAwake":88,"minutesToFallAsleep":0,"startTime":"2018-02-03T22:09:30.000","timeInBed":507,"type":"stages"}],"summary":{"stages":{"deep":94,"light":155,"rem":78,"wake":71},"totalMinutesAsleep":419,"totalSleepRecords":1,"totalTimeInBed":507}}`
17 StartTime: time.Date(2018, time.February, 3, 22, 9, 30, 0, time.UTC),
18 EndTime: time.Date(2018, time.February, 3, 22, 16, 0, 0, time.UTC),
19 Level: SleepLevelLight,
22 StartTime: time.Date(2018, time.February, 3, 22, 10, 0, 0, time.UTC),
23 EndTime: time.Date(2018, time.February, 3, 22, 12, 0, 0, time.UTC),
24 Level: SleepLevelWake,
27 StartTime: time.Date(2018, time.February, 3, 22, 13, 30, 0, time.UTC),
28 EndTime: time.Date(2018, time.February, 3, 22, 14, 0, 0, time.UTC),
29 Level: SleepLevelWake,
32 StartTime: time.Date(2018, time.February, 3, 22, 16, 0, 0, time.UTC),
33 EndTime: time.Date(2018, time.February, 3, 22, 30, 0, 0, time.UTC),
34 Level: SleepLevelWake,
37 StartTime: time.Date(2018, time.February, 3, 22, 30, 0, 0, time.UTC),
38 EndTime: time.Date(2018, time.February, 3, 22, 48, 30, 0, time.UTC),
39 Level: SleepLevelLight,
42 StartTime: time.Date(2018, time.February, 3, 22, 39, 0, 0, time.UTC),
43 EndTime: time.Date(2018, time.February, 3, 22, 40, 0, 0, time.UTC),
44 Level: SleepLevelWake,
47 StartTime: time.Date(2018, time.February, 3, 22, 48, 30, 0, time.UTC),
48 EndTime: time.Date(2018, time.February, 3, 23, 3, 0, 0, time.UTC),
49 Level: SleepLevelWake,
52 StartTime: time.Date(2018, time.February, 3, 23, 3, 0, 0, time.UTC),
53 EndTime: time.Date(2018, time.February, 3, 23, 5, 0, 0, time.UTC),
54 Level: SleepLevelLight,
57 StartTime: time.Date(2018, time.February, 3, 23, 5, 0, 0, time.UTC),
58 EndTime: time.Date(2018, time.February, 3, 23, 15, 0, 0, time.UTC),
59 Level: SleepLevelWake,
62 StartTime: time.Date(2018, time.February, 3, 23, 15, 0, 0, time.UTC),
63 EndTime: time.Date(2018, time.February, 3, 23, 18, 0, 0, time.UTC),
64 Level: SleepLevelLight,
67 StartTime: time.Date(2018, time.February, 3, 23, 18, 0, 0, time.UTC),
68 EndTime: time.Date(2018, time.February, 3, 23, 24, 0, 0, time.UTC),
69 Level: SleepLevelDeep,
72 StartTime: time.Date(2018, time.February, 3, 23, 24, 0, 0, time.UTC),
73 EndTime: time.Date(2018, time.February, 3, 23, 30, 30, 0, time.UTC),
74 Level: SleepLevelLight,
77 StartTime: time.Date(2018, time.February, 3, 23, 30, 30, 0, time.UTC),
78 EndTime: time.Date(2018, time.February, 3, 23, 37, 0, 0, time.UTC),
79 Level: SleepLevelDeep,
82 StartTime: time.Date(2018, time.February, 3, 23, 37, 0, 0, time.UTC),
83 EndTime: time.Date(2018, time.February, 4, 0, 20, 0, 0, time.UTC),
84 Level: SleepLevelLight,
87 StartTime: time.Date(2018, time.February, 3, 23, 52, 0, 0, time.UTC),
88 EndTime: time.Date(2018, time.February, 3, 23, 53, 0, 0, time.UTC),
89 Level: SleepLevelWake,
92 StartTime: time.Date(2018, time.February, 3, 23, 56, 30, 0, time.UTC),
93 EndTime: time.Date(2018, time.February, 3, 23, 57, 0, 0, time.UTC),
94 Level: SleepLevelWake,
97 StartTime: time.Date(2018, time.February, 4, 0, 4, 30, 0, time.UTC),
98 EndTime: time.Date(2018, time.February, 4, 0, 6, 0, 0, time.UTC),
99 Level: SleepLevelWake,
102 StartTime: time.Date(2018, time.February, 4, 0, 17, 30, 0, time.UTC),
103 EndTime: time.Date(2018, time.February, 4, 0, 18, 0, 0, time.UTC),
104 Level: SleepLevelWake,
107 StartTime: time.Date(2018, time.February, 4, 0, 20, 0, 0, time.UTC),
108 EndTime: time.Date(2018, time.February, 4, 0, 38, 0, 0, time.UTC),
109 Level: SleepLevelREM,
112 StartTime: time.Date(2018, time.February, 4, 0, 38, 0, 0, time.UTC),
113 EndTime: time.Date(2018, time.February, 4, 0, 46, 0, 0, time.UTC),
114 Level: SleepLevelWake,
117 StartTime: time.Date(2018, time.February, 4, 0, 46, 0, 0, time.UTC),
118 EndTime: time.Date(2018, time.February, 4, 0, 55, 0, 0, time.UTC),
119 Level: SleepLevelLight,
122 StartTime: time.Date(2018, time.February, 4, 0, 51, 30, 0, time.UTC),
123 EndTime: time.Date(2018, time.February, 4, 0, 52, 0, 0, time.UTC),
124 Level: SleepLevelWake,
127 StartTime: time.Date(2018, time.February, 4, 0, 55, 0, 0, time.UTC),
128 EndTime: time.Date(2018, time.February, 4, 1, 24, 30, 0, time.UTC),
129 Level: SleepLevelDeep,
132 StartTime: time.Date(2018, time.February, 4, 1, 24, 30, 0, time.UTC),
133 EndTime: time.Date(2018, time.February, 4, 1, 31, 0, 0, time.UTC),
134 Level: SleepLevelLight,
137 StartTime: time.Date(2018, time.February, 4, 1, 31, 0, 0, time.UTC),
138 EndTime: time.Date(2018, time.February, 4, 1, 41, 30, 0, time.UTC),
139 Level: SleepLevelWake,
142 StartTime: time.Date(2018, time.February, 4, 1, 41, 30, 0, time.UTC),
143 EndTime: time.Date(2018, time.February, 4, 1, 49, 30, 0, time.UTC),
144 Level: SleepLevelLight,
147 StartTime: time.Date(2018, time.February, 4, 1, 49, 30, 0, time.UTC),
148 EndTime: time.Date(2018, time.February, 4, 2, 5, 0, 0, time.UTC),
149 Level: SleepLevelREM,
152 StartTime: time.Date(2018, time.February, 4, 2, 5, 0, 0, time.UTC),
153 EndTime: time.Date(2018, time.February, 4, 2, 37, 0, 0, time.UTC),
154 Level: SleepLevelLight,
157 StartTime: time.Date(2018, time.February, 4, 2, 6, 30, 0, time.UTC),
158 EndTime: time.Date(2018, time.February, 4, 2, 8, 0, 0, time.UTC),
159 Level: SleepLevelWake,
162 StartTime: time.Date(2018, time.February, 4, 2, 17, 0, 0, time.UTC),
163 EndTime: time.Date(2018, time.February, 4, 2, 17, 30, 0, time.UTC),
164 Level: SleepLevelWake,
167 StartTime: time.Date(2018, time.February, 4, 2, 24, 0, 0, time.UTC),
168 EndTime: time.Date(2018, time.February, 4, 2, 24, 30, 0, time.UTC),
169 Level: SleepLevelWake,
172 StartTime: time.Date(2018, time.February, 4, 2, 37, 0, 0, time.UTC),
173 EndTime: time.Date(2018, time.February, 4, 3, 7, 30, 0, time.UTC),
174 Level: SleepLevelDeep,
177 StartTime: time.Date(2018, time.February, 4, 3, 7, 0, 0, time.UTC),
178 EndTime: time.Date(2018, time.February, 4, 3, 7, 30, 0, time.UTC),
179 Level: SleepLevelWake,
182 StartTime: time.Date(2018, time.February, 4, 3, 7, 30, 0, time.UTC),
183 EndTime: time.Date(2018, time.February, 4, 3, 18, 0, 0, time.UTC),
184 Level: SleepLevelLight,
187 StartTime: time.Date(2018, time.February, 4, 3, 18, 0, 0, time.UTC),
188 EndTime: time.Date(2018, time.February, 4, 3, 47, 0, 0, time.UTC),
189 Level: SleepLevelREM,
192 StartTime: time.Date(2018, time.February, 4, 3, 23, 30, 0, time.UTC),
193 EndTime: time.Date(2018, time.February, 4, 3, 24, 0, 0, time.UTC),
194 Level: SleepLevelWake,
197 StartTime: time.Date(2018, time.February, 4, 3, 42, 0, 0, time.UTC),
198 EndTime: time.Date(2018, time.February, 4, 3, 43, 0, 0, time.UTC),
199 Level: SleepLevelWake,
202 StartTime: time.Date(2018, time.February, 4, 3, 45, 0, 0, time.UTC),
203 EndTime: time.Date(2018, time.February, 4, 3, 45, 30, 0, time.UTC),
204 Level: SleepLevelWake,
207 StartTime: time.Date(2018, time.February, 4, 3, 47, 0, 0, time.UTC),
208 EndTime: time.Date(2018, time.February, 4, 4, 3, 0, 0, time.UTC),
209 Level: SleepLevelWake,
212 StartTime: time.Date(2018, time.February, 4, 4, 3, 0, 0, time.UTC),
213 EndTime: time.Date(2018, time.February, 4, 5, 24, 0, 0, time.UTC),
214 Level: SleepLevelLight,
217 StartTime: time.Date(2018, time.February, 4, 4, 16, 30, 0, time.UTC),
218 EndTime: time.Date(2018, time.February, 4, 4, 17, 0, 0, time.UTC),
219 Level: SleepLevelWake,
222 StartTime: time.Date(2018, time.February, 4, 4, 21, 30, 0, time.UTC),
223 EndTime: time.Date(2018, time.February, 4, 4, 22, 30, 0, time.UTC),
224 Level: SleepLevelWake,
227 StartTime: time.Date(2018, time.February, 4, 4, 47, 30, 0, time.UTC),
228 EndTime: time.Date(2018, time.February, 4, 4, 48, 30, 0, time.UTC),
229 Level: SleepLevelWake,
232 StartTime: time.Date(2018, time.February, 4, 5, 24, 0, 0, time.UTC),
233 EndTime: time.Date(2018, time.February, 4, 5, 55, 30, 0, time.UTC),
234 Level: SleepLevelREM,
237 StartTime: time.Date(2018, time.February, 4, 5, 55, 30, 0, time.UTC),
238 EndTime: time.Date(2018, time.February, 4, 6, 36, 30, 0, time.UTC),
239 Level: SleepLevelLight,
242 StartTime: time.Date(2018, time.February, 4, 6, 29, 0, 0, time.UTC),
243 EndTime: time.Date(2018, time.February, 4, 6, 29, 30, 0, time.UTC),
244 Level: SleepLevelWake,
249 got, err := parseSleep(ctx, []byte(input), time.UTC)
251 t.Errorf("parseSleep() = %v", err)
254 if got, want := len(got.Stages), len(want.Stages); got != want {
255 t.Fatalf("parseSleep() = %d stages, want %d stages", got, want)
258 for i, gotStage := range got.Stages {
259 wantStage := want.Stages[i]
261 if gotStage.Level != wantStage.Level ||
262 !gotStage.StartTime.Equal(wantStage.StartTime) ||
263 !gotStage.EndTime.Equal(wantStage.EndTime) {
264 t.Errorf("Stages[%d] differ; got %+v, want %+v", i, gotStage, wantStage)