package timeext import ( "testing" "time" ) func TestOpenTimeRange_String_Empty(t *testing.T) { r := OpenTimeRange{} if got := r.String(); got != "[]" { t.Errorf("expected [], got %q", got) } } func TestOpenTimeRange_String_FromOnly(t *testing.T) { tm := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{From: &tm} got := r.String() if got == "" || got[0] != '[' || got[len(got)-1] != ']' { t.Errorf("unexpected format: %q", got) } } func TestOpenTimeRange_String_ToOnly(t *testing.T) { tm := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{To: &tm} got := r.String() if got == "" || got[0] != '[' || got[len(got)-1] != ']' { t.Errorf("unexpected format: %q", got) } } func TestOpenTimeRange_String_Both(t *testing.T) { t1 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) t2 := time.Date(2022, 12, 31, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{From: &t1, To: &t2} got := r.String() if got == "" || got[0] != '[' || got[len(got)-1] != ']' { t.Errorf("unexpected format: %q", got) } } func TestOpenTimeRange_Contains_Empty(t *testing.T) { r := OpenTimeRange{} if !r.Contains(time.Now()) { t.Errorf("empty range should contain anything") } } func TestOpenTimeRange_Contains_FromOnly(t *testing.T) { from := time.Date(2022, 6, 1, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{From: &from} if r.Contains(time.Date(2022, 5, 1, 0, 0, 0, 0, time.UTC)) { t.Errorf("should not contain time before From") } if !r.Contains(from) { t.Errorf("should contain From itself") } if !r.Contains(time.Date(2022, 7, 1, 0, 0, 0, 0, time.UTC)) { t.Errorf("should contain time after From") } } func TestOpenTimeRange_Contains_ToOnly(t *testing.T) { to := time.Date(2022, 6, 1, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{To: &to} if !r.Contains(time.Date(2022, 5, 1, 0, 0, 0, 0, time.UTC)) { t.Errorf("should contain time before To") } if r.Contains(to) { t.Errorf("should not contain To itself (exclusive)") } if r.Contains(time.Date(2022, 7, 1, 0, 0, 0, 0, time.UTC)) { t.Errorf("should not contain time after To") } } func TestOpenTimeRange_Contains_Both(t *testing.T) { from := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) to := time.Date(2022, 12, 31, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{From: &from, To: &to} if r.Contains(time.Date(2021, 12, 31, 0, 0, 0, 0, time.UTC)) { t.Errorf("should not contain time before From") } if !r.Contains(time.Date(2022, 6, 1, 0, 0, 0, 0, time.UTC)) { t.Errorf("should contain time within range") } if r.Contains(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)) { t.Errorf("should not contain time after To") } } func TestNewOpenTimeRange_Nil(t *testing.T) { if NewOpenTimeRange(nil, nil) != nil { t.Errorf("expected nil for both nil inputs") } } func TestNewOpenTimeRange_FromOnly(t *testing.T) { tm := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) r := NewOpenTimeRange(&tm, nil) if r == nil || r.From == nil || !r.From.Equal(tm) || r.To != nil { t.Errorf("unexpected result: %v", r) } } func TestNewOpenTimeRange_ToOnly(t *testing.T) { tm := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) r := NewOpenTimeRange(nil, &tm) if r == nil || r.To == nil || !r.To.Equal(tm) || r.From != nil { t.Errorf("unexpected result: %v", r) } } func TestNewOpenTimeRange_Both(t *testing.T) { from := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) to := time.Date(2022, 12, 31, 0, 0, 0, 0, time.UTC) r := NewOpenTimeRange(&from, &to) if r == nil || !r.From.Equal(from) || !r.To.Equal(to) { t.Errorf("unexpected result: %v", r) } } func TestOpenTimeRange_ToMongoPipeline_Empty(t *testing.T) { r := OpenTimeRange{} pipeline := r.ToMongoPipeline("ts") if len(pipeline) != 0 { t.Errorf("expected empty pipeline, got %v", pipeline) } } func TestOpenTimeRange_ToMongoPipeline_FromOnly(t *testing.T) { from := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{From: &from} pipeline := r.ToMongoPipeline("ts") if len(pipeline) != 1 { t.Errorf("expected 1 stage, got %d", len(pipeline)) } } func TestOpenTimeRange_ToMongoPipeline_ToOnly(t *testing.T) { to := time.Date(2022, 12, 31, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{To: &to} pipeline := r.ToMongoPipeline("ts") if len(pipeline) != 1 { t.Errorf("expected 1 stage, got %d", len(pipeline)) } } func TestOpenTimeRange_ToMongoPipeline_Both(t *testing.T) { from := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) to := time.Date(2022, 12, 31, 0, 0, 0, 0, time.UTC) r := OpenTimeRange{From: &from, To: &to} pipeline := r.ToMongoPipeline("ts") if len(pipeline) != 2 { t.Errorf("expected 2 stages, got %d", len(pipeline)) } } func TestOpenTimeRange_AppendToMongoPipeline_Nil(t *testing.T) { var r *OpenTimeRange existing := []any{"existing"} got := r.AppendToMongoPipeline(existing, "ts") if len(got) != 1 { t.Errorf("expected unchanged pipeline, got %v", got) } } func TestOpenTimeRange_AppendToMongoPipeline_NonNil(t *testing.T) { from := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC) r := &OpenTimeRange{From: &from} existing := []any{"existing"} got := r.AppendToMongoPipeline(existing, "ts") if len(got) != 2 { t.Errorf("expected pipeline with 2 entries, got %v", got) } }