mirror of
https://github.com/taigrr/most-specific-period.git
synced 2026-04-02 03:38:41 -07:00
Merge pull request #1 from ethanholz/generate-timeline
Added functionality to generate timeline and preliminary support for help function
This commit is contained in:
13
main.go
13
main.go
@@ -20,9 +20,11 @@ type Period struct {
|
|||||||
func (p Period) GetEndTime() time.Time {
|
func (p Period) GetEndTime() time.Time {
|
||||||
return p.EndTime
|
return p.EndTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Period) GetStartTime() time.Time {
|
func (p Period) GetStartTime() time.Time {
|
||||||
return p.StartTime
|
return p.StartTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Period) GetIdentifier() string {
|
func (p Period) GetIdentifier() string {
|
||||||
return p.Identifier
|
return p.Identifier
|
||||||
}
|
}
|
||||||
@@ -33,13 +35,18 @@ func init() {
|
|||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func warnMessage() {
|
func warnMessage() {
|
||||||
fmt.Print("Please type your date formats as follows, hit return between each field (RFC 3339), and hit Control+D to signal you are complete: \nIdentifier: id\nStartTime: 2019-10-12T07:20:50.52Z\nEndTime: 2019-10-12T07:20:50.52Z\n")
|
fmt.Print("Please type your date formats as follows, hit return between each field (RFC 3339), and hit Control+D to signal you are complete: \nIdentifier: id\nStartTime: 2019-10-12T07:20:50.52Z\nEndTime: 2019-10-12T07:20:50.52Z\n")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
help := flag.Bool("h", false, "displays help command")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
if *help {
|
||||||
|
fmt.Println("Help goes here")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
terminal := false
|
terminal := false
|
||||||
fi, _ := os.Stdin.Stat()
|
fi, _ := os.Stdin.Stat()
|
||||||
if (fi.Mode() & os.ModeCharDevice) == 0 {
|
if (fi.Mode() & os.ModeCharDevice) == 0 {
|
||||||
@@ -107,4 +114,8 @@ func main() {
|
|||||||
fmt.Printf("\nThe MSP from the list was: ")
|
fmt.Printf("\nThe MSP from the list was: ")
|
||||||
}
|
}
|
||||||
fmt.Printf("%s\n", m)
|
fmt.Printf("%s\n", m)
|
||||||
|
vals := msp.GenerateTimeline(periods...)
|
||||||
|
for _, val := range vals {
|
||||||
|
fmt.Println(val)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
msp/timeline.go
Normal file
31
msp/timeline.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package msp
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Outputs a formatted timeline of periods
|
||||||
|
func GenerateTimeline(periods ...Period) (out []string) {
|
||||||
|
if len(periods) == 0 {
|
||||||
|
out = []string{}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
periodsByID := make(map[string]Period)
|
||||||
|
ids := FlattenPeriods(periods...)
|
||||||
|
for _, val := range periods {
|
||||||
|
id := val.GetIdentifier()
|
||||||
|
periodsByID[id] = val
|
||||||
|
}
|
||||||
|
start := periodsByID[ids[0]].GetStartTime()
|
||||||
|
for _, val := range ids {
|
||||||
|
next, err := GetNextChangeOver(start, periods...)
|
||||||
|
if err == nil {
|
||||||
|
if next.Equal(periodsByID[val].GetStartTime()) {
|
||||||
|
start = periodsByID[val].GetStartTime()
|
||||||
|
next = periodsByID[val].GetEndTime()
|
||||||
|
}
|
||||||
|
frame := fmt.Sprintf("%s\t%s\t%s\n", val, start, next)
|
||||||
|
out = append(out, frame)
|
||||||
|
start = next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
169
msp/timeline_test.go
Normal file
169
msp/timeline_test.go
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
package msp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// (periods ...Period) (id string, err error) {
|
||||||
|
func TestGenerateTime(t *testing.T) {
|
||||||
|
now := time.Now()
|
||||||
|
testCases := []struct {
|
||||||
|
ts time.Time
|
||||||
|
testID string
|
||||||
|
result []string
|
||||||
|
periods []Period
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
testID: "No choices",
|
||||||
|
ts: now,
|
||||||
|
result: []string{},
|
||||||
|
periods: []Period{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testID: "Two Choices, shorter is second",
|
||||||
|
ts: now,
|
||||||
|
result: []string{
|
||||||
|
fmt.Sprintf("A\t%s\t%s\n", now.Add(-5*time.Minute), now.Add(-2*time.Minute)),
|
||||||
|
fmt.Sprintf("B\t%s\t%s\n", now.Add(-2*time.Minute), now.Add(time.Minute)),
|
||||||
|
},
|
||||||
|
periods: []Period{
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-5 * time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "A",
|
||||||
|
},
|
||||||
|
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,
|
||||||
|
result: []string{
|
||||||
|
fmt.Sprintf("A\t%s\t%s\n", now.Add(-1*time.Hour*24*365), now.Add(-5*time.Minute)),
|
||||||
|
fmt.Sprintf("B\t%s\t%s\n", now.Add(-5*time.Minute), now.Add(time.Minute)),
|
||||||
|
},
|
||||||
|
periods: []Period{
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-1 * time.Hour * 24 * 365),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "A",
|
||||||
|
},
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-5 * time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "B",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testID: "Two Choices, shorter is first",
|
||||||
|
ts: now,
|
||||||
|
result: []string{
|
||||||
|
fmt.Sprintf("B\t%s\t%s\n", now.Add(-5*time.Minute), now.Add(-2*time.Minute)),
|
||||||
|
fmt.Sprintf("A\t%s\t%s\n", now.Add(-2*time.Minute), now.Add(time.Minute)),
|
||||||
|
},
|
||||||
|
periods: []Period{
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-2 * time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "A",
|
||||||
|
},
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-5 * time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "B",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testID: "Two Choices, one in the past",
|
||||||
|
ts: now,
|
||||||
|
result: []string{
|
||||||
|
fmt.Sprintf("B\t%s\t%s\n", now.Add(-2*time.Minute), now.Add(-time.Minute)),
|
||||||
|
fmt.Sprintf("A\t%s\t%s\n", now.Add(-time.Minute), now.Add(time.Minute)),
|
||||||
|
},
|
||||||
|
periods: []Period{
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "A",
|
||||||
|
},
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-2 * time.Minute),
|
||||||
|
EndTime: now.Add(-time.Minute),
|
||||||
|
Identifier: "B",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testID: "Two Choices, one invalid",
|
||||||
|
ts: now,
|
||||||
|
result: []string{
|
||||||
|
fmt.Sprintf("B\t%s\t%s\n", now.Add(-2*time.Minute), now.Add(time.Minute)),
|
||||||
|
},
|
||||||
|
periods: []Period{
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(time.Minute),
|
||||||
|
EndTime: now.Add(-time.Minute),
|
||||||
|
Identifier: "A",
|
||||||
|
},
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-2 * time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "B",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testID: "Two Choices, Identical periods",
|
||||||
|
ts: now,
|
||||||
|
result: []string{
|
||||||
|
fmt.Sprintf("B\t%s\t%s\n", now.Add(-time.Minute), now.Add(time.Minute)),
|
||||||
|
},
|
||||||
|
periods: []Period{
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "A",
|
||||||
|
},
|
||||||
|
TimeWindow{
|
||||||
|
StartTime: now.Add(-time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "B",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testID: "One choice",
|
||||||
|
ts: now,
|
||||||
|
result: []string{
|
||||||
|
fmt.Sprintf("A\t%s\t%s\n", now.Add(-time.Minute), now.Add(time.Minute)),
|
||||||
|
},
|
||||||
|
periods: []Period{TimeWindow{
|
||||||
|
StartTime: now.Add(-time.Minute),
|
||||||
|
EndTime: now.Add(time.Minute),
|
||||||
|
Identifier: "A",
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(fmt.Sprintf("%s", tc.testID), func(t *testing.T) {
|
||||||
|
timeline := GenerateTimeline(tc.periods...)
|
||||||
|
if len(timeline) != len(tc.result) {
|
||||||
|
t.Fatalf("Time line had %d results, expected %d", len(timeline), len(tc.result))
|
||||||
|
}
|
||||||
|
for idx, period := range timeline {
|
||||||
|
if period != tc.result[idx] {
|
||||||
|
t.Errorf("Expected:\t%s\t\tHad:\t%s", period, tc.result[idx])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user