Use a struct instead of string slices

This commit is contained in:
2022-10-14 22:04:08 -07:00
parent f989049717
commit 2e68bb06af
5 changed files with 455 additions and 213 deletions

View File

@@ -123,13 +123,13 @@ func main() {
} }
vals := msp.GenerateTimeline(periods...) vals := msp.GenerateTimeline(periods...)
fmt.Print("\n") fmt.Print("\nTimeline of changeovers:\n")
for _, val := range vals { for _, val := range vals {
fmt.Print(val) fmt.Println(val)
} }
m, err := msp.MostSpecificPeriod(start, periods...) m, err := msp.MostSpecificPeriod(start, periods...)
if err != nil { if err != nil {
fmt.Printf("No significant period found") fmt.Printf("No significant period found\n")
os.Exit(1) os.Exit(1)
} }
if terminal { if terminal {

View File

@@ -26,81 +26,137 @@ func TestGetChangeOvers(t *testing.T) {
testID string testID string
result []time.Time result []time.Time
periods []Period periods []Period
}{{testID: "No choices", }{
ts: now, {
result: []time.Time{}, testID: "No choices",
periods: []Period{}}, ts: now,
{testID: "Two Choices, shorter is second", result: []time.Time{},
periods: []Period{},
},
{
testID: "Two Choices, shorter is second",
ts: now, ts: now,
result: []time.Time{now.Add(-5 * time.Minute), now.Add(-2 * time.Minute), now.Add(time.Minute)}, result: []time.Time{now.Add(-5 * time.Minute), now.Add(-2 * time.Minute), now.Add(time.Minute)},
periods: []Period{TimeWindow{StartTime: now.Add(-5 * time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-5 * time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Two Choices, one is a year, other a minute", },
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Two Choices, one is a year, other a minute",
ts: now, ts: now,
result: []time.Time{now.Add(-1 * time.Hour * 24 * 365), now.Add(-5 * time.Minute), now.Add(time.Minute)}, result: []time.Time{now.Add(-1 * time.Hour * 24 * 365), now.Add(-5 * time.Minute), now.Add(time.Minute)},
periods: []Period{TimeWindow{StartTime: now.Add(-1 * time.Hour * 24 * 365), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-1 * time.Hour * 24 * 365),
TimeWindow{StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{testID: "Two Choices, shorter is first", {
testID: "Two Choices, shorter is first",
ts: now, ts: now,
result: []time.Time{now.Add(-5 * time.Minute), now.Add(-2 * time.Minute), now.Add(time.Minute)}, result: []time.Time{now.Add(-5 * time.Minute), now.Add(-2 * time.Minute), now.Add(time.Minute)},
periods: []Period{TimeWindow{StartTime: now.Add(-2 * time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-2 * time.Minute),
TimeWindow{StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Two Choices, one in the past", },
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Two Choices, one in the past",
ts: now, ts: now,
result: []time.Time{now.Add(-2 * time.Minute), now.Add(-time.Minute), now.Add(time.Minute)}, result: []time.Time{now.Add(-2 * time.Minute), now.Add(-time.Minute), now.Add(time.Minute)},
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute), EndTime: now.Add(time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(-time.Minute), EndTime: now.Add(-time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "Two Choices, one invalid", },
},
},
{
testID: "Two Choices, one invalid",
ts: now, ts: now,
result: []time.Time{now.Add(-2 * time.Minute), now.Add(time.Minute)}, result: []time.Time{now.Add(-2 * time.Minute), now.Add(time.Minute)},
periods: []Period{TimeWindow{StartTime: now.Add(time.Minute), periods: []Period{
EndTime: now.Add(-time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute), EndTime: now.Add(-time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "Two Choices, Identical periods", },
},
},
{
testID: "Two Choices, Identical periods",
ts: now, ts: now,
result: []time.Time{now.Add(-time.Minute), now.Add(time.Minute)}, result: []time.Time{now.Add(-time.Minute), now.Add(time.Minute)},
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-time.Minute),
TimeWindow{StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "One choice", },
TimeWindow{
StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "One choice",
ts: now, ts: now,
result: []time.Time{now.Add(-time.Minute), now.Add(time.Minute)}, result: []time.Time{now.Add(-time.Minute), now.Add(time.Minute)},
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{TimeWindow{
StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "A"}}}} Identifier: "A",
}},
},
}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) { t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) {
changeovers := GetChangeOvers(tc.periods...) changeovers := GetChangeOvers(tc.periods...)
if !slicesEqual(changeovers, tc.result) { if !slicesEqual(changeovers, tc.result) {
t.Errorf("Expected %v but got %v", tc.result, changeovers) t.Errorf("Expected %v but got %v", tc.result, changeovers)
} }
}) })
} }
} }
func TestFlattenPeriods(t *testing.T) { func TestFlattenPeriods(t *testing.T) {
// use a static timestamp to make sure tests don't fail on slower systems or during a process pause // use a static timestamp to make sure tests don't fail on slower systems or during a process pause
now := time.Now() now := time.Now()
@@ -110,92 +166,158 @@ func TestFlattenPeriods(t *testing.T) {
result []string result []string
err error err error
periods []Period periods []Period
}{{testID: "No choices", }{
ts: now, {
result: []string{}, testID: "No choices",
err: ErrNoValidPeriods, ts: now,
periods: []Period{}}, result: []string{},
{testID: "Two Choices, shorter is second", err: ErrNoValidPeriods,
periods: []Period{},
},
{
testID: "Two Choices, shorter is second",
ts: now, ts: now,
result: []string{"A", "B"}, result: []string{"A", "B"},
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-5 * time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-5 * time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Two Choices, one is a year, other a minute", },
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Two Choices, one is a year, other a minute",
ts: now, ts: now,
result: []string{"A", "B"}, result: []string{"A", "B"},
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-1 * time.Hour * 24 * 365), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-1 * time.Hour * 24 * 365),
TimeWindow{StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{testID: "Two Choices, shorter is first", {
testID: "Two Choices, shorter is first",
ts: now, ts: now,
result: []string{"B", "A"}, result: []string{"B", "A"},
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-2 * time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-2 * time.Minute),
TimeWindow{StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Two Choices, one in the past", },
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Two Choices, one in the past",
ts: now, ts: now,
result: []string{"B", "A"}, result: []string{"B", "A"},
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute), EndTime: now.Add(time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(-time.Minute), EndTime: now.Add(-time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "Two Choices, one invalid", },
},
},
{
testID: "Two Choices, one invalid",
ts: now, ts: now,
result: []string{"B"}, result: []string{"B"},
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(time.Minute), periods: []Period{
EndTime: now.Add(-time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute), EndTime: now.Add(-time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "Two Choices, Identical periods", },
},
},
{
testID: "Two Choices, Identical periods",
ts: now, ts: now,
result: []string{"B"}, result: []string{"B"},
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-time.Minute),
TimeWindow{StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Triple Nested Periods", },
TimeWindow{
StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Triple Nested Periods",
ts: now, ts: now,
result: []string{"A", "B", "C", "B", "A"}, result: []string{"A", "B", "C", "B", "A"},
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-15 * time.Minute), periods: []Period{
EndTime: now.Add(15 * time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-15 * time.Minute),
TimeWindow{StartTime: now.Add(-5 * time.Minute), EndTime: now.Add(15 * time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(5 * time.Minute), EndTime: now.Add(5 * time.Minute),
Identifier: "C"}, Identifier: "C",
TimeWindow{StartTime: now.Add(-10 * time.Minute), },
TimeWindow{
StartTime: now.Add(-10 * time.Minute),
EndTime: now.Add(10 * time.Minute), EndTime: now.Add(10 * time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "One choice", },
},
},
{
testID: "One choice",
ts: now, ts: now,
result: []string{"A"}, result: []string{"A"},
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{TimeWindow{
StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "A"}}}} Identifier: "A",
}},
},
}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) { t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) {
@@ -203,10 +325,10 @@ func TestFlattenPeriods(t *testing.T) {
if !slicesEqual(changeovers, tc.result) { if !slicesEqual(changeovers, tc.result) {
t.Errorf("Expected %v but got %v", tc.result, changeovers) t.Errorf("Expected %v but got %v", tc.result, changeovers)
} }
}) })
} }
} }
func TestGetNextChangeOver(t *testing.T) { func TestGetNextChangeOver(t *testing.T) {
// use a static timestamp to make sure tests don't fail on slower systems or during a process pause // use a static timestamp to make sure tests don't fail on slower systems or during a process pause
now := time.Now() now := time.Now()
@@ -216,79 +338,135 @@ func TestGetNextChangeOver(t *testing.T) {
result time.Time result time.Time
err error err error
periods []Period periods []Period
}{{testID: "No choices", }{
ts: now, {
result: time.Time{}, testID: "No choices",
err: ErrNoNextChangeover, ts: now,
periods: []Period{}}, result: time.Time{},
{testID: "Two Choices, shorter is second", err: ErrNoNextChangeover,
periods: []Period{},
},
{
testID: "Two Choices, shorter is second",
ts: now, ts: now,
result: now.Add(time.Minute), result: now.Add(time.Minute),
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-5 * time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-5 * time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Two Choices, one is a year, other a minute", },
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Two Choices, one is a year, other a minute",
ts: now, ts: now,
result: now.Add(time.Minute), result: now.Add(time.Minute),
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-1 * time.Hour * 24 * 365), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-1 * time.Hour * 24 * 365),
TimeWindow{StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{testID: "Two Choices, shorter is first", {
testID: "Two Choices, shorter is first",
ts: now, ts: now,
result: now.Add(time.Minute), result: now.Add(time.Minute),
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-2 * time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-2 * time.Minute),
TimeWindow{StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Two Choices, one in the past", },
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Two Choices, one in the past",
ts: now, ts: now,
result: now.Add(time.Minute), result: now.Add(time.Minute),
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute), EndTime: now.Add(time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(-time.Minute), EndTime: now.Add(-time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "Two Choices, one invalid", },
},
},
{
testID: "Two Choices, one invalid",
ts: now, ts: now,
result: now.Add(time.Minute), result: now.Add(time.Minute),
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(time.Minute), periods: []Period{
EndTime: now.Add(-time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute), EndTime: now.Add(-time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "Two Choices, Identical periods", },
},
},
{
testID: "Two Choices, Identical periods",
ts: now, ts: now,
result: now.Add(time.Minute), result: now.Add(time.Minute),
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-time.Minute),
TimeWindow{StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "One choice", },
TimeWindow{
StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "One choice",
ts: now, ts: now,
result: now.Add(time.Minute), result: now.Add(time.Minute),
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{TimeWindow{
StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "A"}}}} Identifier: "A",
}},
},
}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) { t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) {
ts, err := GetNextChangeOver(now, tc.periods...) ts, err := GetNextChangeOver(now, tc.periods...)
@@ -298,7 +476,6 @@ func TestGetNextChangeOver(t *testing.T) {
if ts != tc.result { if ts != tc.result {
t.Errorf("Got %v but expected %v", ts, tc.result) t.Errorf("Got %v but expected %v", ts, tc.result)
} }
}) })
} }
} }

View File

@@ -6,23 +6,7 @@ import (
"time" "time"
) )
type TimeWindow struct { // (periods ...Period) (id string, err error) {
StartTime time.Time
EndTime time.Time
Identifier string
}
func (p TimeWindow) GetIdentifier() string {
return p.Identifier
}
func (p TimeWindow) GetEndTime() time.Time {
return p.EndTime
}
func (p TimeWindow) GetStartTime() time.Time {
return p.StartTime
}
//(periods ...Period) (id string, err error) {
func TestMostSpecificPeriod(t *testing.T) { func TestMostSpecificPeriod(t *testing.T) {
// use a static timestamp to make sure tests don't fail on slower systems or during a process pause // use a static timestamp to make sure tests don't fail on slower systems or during a process pause
now := time.Now() now := time.Now()
@@ -32,79 +16,135 @@ func TestMostSpecificPeriod(t *testing.T) {
result string result string
err error err error
periods []Period periods []Period
}{{testID: "No choices", }{
ts: now, {
result: "", testID: "No choices",
err: ErrNoValidPeriods, ts: now,
periods: []Period{}}, result: "",
{testID: "Two Choices, shorter is second", err: ErrNoValidPeriods,
periods: []Period{},
},
{
testID: "Two Choices, shorter is second",
ts: now, ts: now,
result: "B", result: "B",
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-5 * time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-5 * time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Two Choices, one is a year, other a minute", },
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Two Choices, one is a year, other a minute",
ts: now, ts: now,
result: "B", result: "B",
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-1 * time.Hour * 24 * 365), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-1 * time.Hour * 24 * 365),
TimeWindow{StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{testID: "Two Choices, shorter is first", {
testID: "Two Choices, shorter is first",
ts: now, ts: now,
result: "A", result: "A",
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-2 * time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-2 * time.Minute),
TimeWindow{StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "Two Choices, one in the past", },
TimeWindow{
StartTime: now.Add(-5 * time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "Two Choices, one in the past",
ts: now, ts: now,
result: "A", result: "A",
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute), EndTime: now.Add(time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(-time.Minute), EndTime: now.Add(-time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "Two Choices, one invalid", },
},
},
{
testID: "Two Choices, one invalid",
ts: now, ts: now,
result: "B", result: "B",
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(time.Minute), periods: []Period{
EndTime: now.Add(-time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(time.Minute),
TimeWindow{StartTime: now.Add(-2 * time.Minute), EndTime: now.Add(-time.Minute),
Identifier: "A",
},
TimeWindow{
StartTime: now.Add(-2 * time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "B",
{testID: "Two Choices, Identical periods", },
},
},
{
testID: "Two Choices, Identical periods",
ts: now, ts: now,
result: "B", result: "B",
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{
EndTime: now.Add(time.Minute), TimeWindow{
Identifier: "A"}, StartTime: now.Add(-time.Minute),
TimeWindow{StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "B"}}}, Identifier: "A",
{testID: "One choice", },
TimeWindow{
StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute),
Identifier: "B",
},
},
},
{
testID: "One choice",
ts: now, ts: now,
result: "A", result: "A",
err: nil, err: nil,
periods: []Period{TimeWindow{StartTime: now.Add(-time.Minute), periods: []Period{TimeWindow{
StartTime: now.Add(-time.Minute),
EndTime: now.Add(time.Minute), EndTime: now.Add(time.Minute),
Identifier: "A"}}}} Identifier: "A",
}},
},
}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) { t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) {
id, err := MostSpecificPeriod(tc.ts, tc.periods...) id, err := MostSpecificPeriod(tc.ts, tc.periods...)
@@ -114,7 +154,6 @@ func TestMostSpecificPeriod(t *testing.T) {
if err != tc.err { if err != tc.err {
t.Errorf("Error '%v' does not match expected '%v'", err, tc.err) t.Errorf("Error '%v' does not match expected '%v'", err, tc.err)
} }
}) })
} }
} }

View File

@@ -1,11 +1,38 @@
package msp package msp
import "fmt" import (
"fmt"
"time"
)
type TimeWindow struct {
StartTime time.Time
EndTime time.Time
Identifier string
}
func (p TimeWindow) GetIdentifier() string {
return p.Identifier
}
func (p TimeWindow) GetEndTime() time.Time {
return p.EndTime
}
func (p TimeWindow) GetStartTime() time.Time {
return p.StartTime
}
func (t TimeWindow) String() string {
return fmt.Sprintf("%s\t%s\t%s",
t.GetIdentifier(),
t.GetStartTime(),
t.GetEndTime())
}
// Outputs a formatted timeline of periods // Outputs a formatted timeline of periods
func GenerateTimeline(periods ...Period) (out []string) { func GenerateTimeline(periods ...Period) (out []Period) {
if len(periods) == 0 { if len(periods) == 0 {
out = []string{}
return out return out
} }
periodsByID := make(map[string]Period) periodsByID := make(map[string]Period)
@@ -22,8 +49,7 @@ func GenerateTimeline(periods ...Period) (out []string) {
start = periodsByID[val].GetStartTime() start = periodsByID[val].GetStartTime()
next = periodsByID[val].GetEndTime() next = periodsByID[val].GetEndTime()
} }
frame := fmt.Sprintf("%s\t%s\t%s\n", val, start, next) out = append(out, TimeWindow{StartTime: start, EndTime: next, Identifier: val})
out = append(out, frame)
start = next start = next
} }
} }

View File

@@ -269,7 +269,7 @@ func TestGenerateTime(t *testing.T) {
t.Fatalf("Time line had %d results, expected %d", len(timeline), len(tc.result)) t.Fatalf("Time line had %d results, expected %d", len(timeline), len(tc.result))
} }
for idx, period := range timeline { for idx, period := range timeline {
if period != tc.result[idx] { if period.(TimeWindow).String()+"\n" != tc.result[idx] {
t.Errorf("Expected:\t%s\nHad:\t%s", period, tc.result[idx]) t.Errorf("Expected:\t%s\nHad:\t%s", period, tc.result[idx])
} }
} }