package fitbit import ( "context" "testing" "time" ) func TestParseSleep(t *testing.T) { ctx := context.Background() 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}}` want := &Sleep{ Stages: []SleepStage{ SleepStage{ StartTime: time.Date(2018, time.February, 3, 22, 9, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 22, 16, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 22, 10, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 22, 12, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 22, 13, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 22, 14, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 22, 16, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 22, 30, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 22, 30, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 22, 48, 30, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 22, 39, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 22, 40, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 22, 48, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 3, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 3, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 5, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 5, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 15, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 15, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 18, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 18, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 24, 0, 0, time.UTC), Level: SleepLevelDeep, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 24, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 30, 30, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 30, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 37, 0, 0, time.UTC), Level: SleepLevelDeep, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 37, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 0, 20, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 52, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 53, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 3, 23, 56, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 3, 23, 57, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 0, 4, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 0, 6, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 0, 17, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 0, 18, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 0, 20, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 0, 38, 0, 0, time.UTC), Level: SleepLevelREM, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 0, 38, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 0, 46, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 0, 46, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 0, 55, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 0, 51, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 0, 52, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 0, 55, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 1, 24, 30, 0, time.UTC), Level: SleepLevelDeep, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 1, 24, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 1, 31, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 1, 31, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 1, 41, 30, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 1, 41, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 1, 49, 30, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 1, 49, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 2, 5, 0, 0, time.UTC), Level: SleepLevelREM, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 2, 5, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 2, 37, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 2, 6, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 2, 8, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 2, 17, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 2, 17, 30, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 2, 24, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 2, 24, 30, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 2, 37, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 3, 7, 30, 0, time.UTC), Level: SleepLevelDeep, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 3, 7, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 3, 7, 30, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 3, 7, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 3, 18, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 3, 18, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 3, 47, 0, 0, time.UTC), Level: SleepLevelREM, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 3, 23, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 3, 24, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 3, 42, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 3, 43, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 3, 45, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 3, 45, 30, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 3, 47, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 4, 3, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 4, 3, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 5, 24, 0, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 4, 16, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 4, 17, 0, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 4, 21, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 4, 22, 30, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 4, 47, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 4, 48, 30, 0, time.UTC), Level: SleepLevelWake, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 5, 24, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 5, 55, 30, 0, time.UTC), Level: SleepLevelREM, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 5, 55, 30, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 6, 36, 30, 0, time.UTC), Level: SleepLevelLight, }, SleepStage{ StartTime: time.Date(2018, time.February, 4, 6, 29, 0, 0, time.UTC), EndTime: time.Date(2018, time.February, 4, 6, 29, 30, 0, time.UTC), Level: SleepLevelWake, }, }, } got, err := parseSleep(ctx, []byte(input), time.UTC) if err != nil { t.Errorf("parseSleep() = %v", err) } if got, want := len(got.Stages), len(want.Stages); got != want { t.Fatalf("parseSleep() = %d stages, want %d stages", got, want) } for i, gotStage := range got.Stages { wantStage := want.Stages[i] if gotStage.Level != wantStage.Level || !gotStage.StartTime.Equal(wantStage.StartTime) || !gotStage.EndTime.Equal(wantStage.EndTime) { t.Errorf("Stages[%d] differ; got %+v, want %+v", i, gotStage, wantStage) } } }