diff --git a/README.md b/README.md index 6cb97cd..e7b35b5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,59 @@ -# Cadence +# goCadence +Go module focused on recurring time periods -GO library that provides a Cadence object that allows the ability to define time periods and use them to calculate dates \ No newline at end of file +## Defined Cadence Values + + | Key | Description . | + |----------------|----------------------| + | ANNUALLY | once per year | + | BIANNUALLY | every two years | + | BIMONTHLY | every two months | + | BIWEEKLY | every two weeks | + | DAILY | every day | + | MONTHLY | once per month | + | ONCE | one time only | + | QUADWEEKLY | every four weeks | + | QUARTERLY | four times per year | + | SEMIANNUALLY | twice per year | + | SEMIMONTHLY | twice per month | + | TREANNUALLY | every three years | + | TREQUADWEEKLY | every twelve weeks | + | TRIANNUALLY | three times per year | + | WEEKLY | once per week | + +## API + + * **goCadenceVersion()** -> *string* + * **Parameters:** *none* + * **Return:** *string* in the format of Major.Minor.Patch + * A function that will return the version string to determine what features are available + * **New(key *string*)** -> CadenceObj + * **Parameters:** *key(string)* + * **Return:** *CadenceObj* + * Function to initialize a CadenceObj that follows the CadenceInf interface, defined via a key to identify the Cadence wanted + +## CadenceObj + + * **Properties:** + * **String:** A printable version of the cadence name + * **Example** BIWEEKLY.String() -> "bi-weekly" + * **Description:** a description of the cadence + * **Example:** BIWEEKLY.Description() -> "every two weeks" + * **Methods:** + * **TimesIn(cad CadenceObj)** -> *float64* + * **Parameters:** Cadence Object + * **Return:** *float64* + * A method to return the nunber of times the cadence will exist with the given cadence + * Example -> A cadence of Semi-Annually will occur 2.0 times in a cadence of Annually + +## Misc. Notes + + * Cadence of SEMIMONTHLY currently defaults to the 15th and the last day of the month + +## Future Features + + * Setting to disallow Saturdays + * Setting to disallow Sundays + * Setting to disallow Holidays + * Allow dates to be advanced to next day when disallowed + * Allow dates to be pushed backward to previous day when disallowed diff --git a/cadence.go b/cadence.go new file mode 100644 index 0000000..4f115e7 --- /dev/null +++ b/cadence.go @@ -0,0 +1,124 @@ +package cadence + +import ( + "errors" + "strings" + "time" +) + +const ( + appVersion string = "0.0.3" +) + +type CadenceEngine struct { + Version string +} + +func (ce *CadenceEngine) New(key string) (co CadenceObj, err error) { + idx := strings.ToUpper(key) + + if obj, found := cadences[idx]; found { + co = obj + } else { + err = errors.New("ERROR: Cadences: Invalid Cadence Key") + } + + return +} + +type CadenceObj struct { + Key string + Value int64 + String string + Description string +} + +func (co *CadenceObj) TimesIn(secondCo CadenceObj) (ans float64, err error) { + if co.Value == 0 { + ans = 1.0 + } else { + ans = float64(co.Value) / float64(secondCo.Value) + } + + return +} + +func (co *CadenceObj) Next(baseDate time.Time) (newDate time.Time, err error) { + switch co.Key { + case "ANNUALLY": + newDate = baseDate.AddDate(1, 0, 0) + case "BIANNUALLY": + newDate = baseDate.AddDate(2, 0, 0) + case "BIMONTHLY": + newDate = baseDate.AddDate(0, 2, 0) + case "BIWEEKLY": + newDate = baseDate.AddDate(0, 0, 14) + case "DAILY": + newDate = baseDate.AddDate(0, 0, 1) + case "MONTHLY": + newDate = baseDate.AddDate(0, 1, 0) + case "ONCE": + newDate = baseDate + case "QUADWEEKLY": + newDate = baseDate.AddDate(0, 0, 28) + case "QUARTERLY": + newDate = baseDate.AddDate(0, 3, 0) + case "SEMIANNUALLY": + newDate = baseDate.AddDate(0, 6, 0) + case "SEMIMONTHLY": + m := baseDate.Month() + d := baseDate.Day() + y := baseDate.Year() + + if d >= 15 { + newDate = time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC) + } else { + newDate = time.Date(y, m, 15, 0, 0, 0, 0, time.UTC) + } + + if newDate == baseDate { + newDate = time.Date(y, m+1, 15, 0, 0, 0, 0, time.UTC) + } + case "TREANNUALLY": + newDate = baseDate.AddDate(3, 0, 0) + case "TREQUADWEEKLY": + newDate = baseDate.AddDate(0, 0, 84) + case "TRIANNUALLY": + newDate = baseDate.AddDate(0, 4, 0) + case "WEEKLY": + newDate = baseDate.AddDate(0, 0, 7) + } + + return +} + +func (co *CadenceObj) NextN(baseDate time.Time, idx int) (newDate time.Time, err error) { + newDate = baseDate + for i := 0; i < idx; i++ { + newDate, err = co.Next(newDate) + } + + return +} + +var ( + Cadence = CadenceEngine{appVersion} + + cadences = map[string]CadenceObj{ + "ANNUALLY": {Key: "ANNUALLY", Value: 84, String: "annually", Description: "once per year"}, + "BIANNUALLY": {Key: "BIANNUALLY", Value: 42, String: "bi-annually", Description: "every two years"}, + "BIMONTHLY": {Key: "BIMONTHLY", Value: 504, String: "bi-monthly", Description: "every two months"}, + "BIWEEKLY": {Key: "BIWEEKLY", Value: 2190, String: "bi-weekly", Description: "every two weeks"}, + "DAILY": {Key: "DAILY", Value: 30660, String: "daily", Description: "every day"}, + "MONTHLY": {Key: "MONTHLY", Value: 1008, String: "monthly", Description: "once per month"}, + "ONCE": {Key: "ONCE", Value: 0, String: "once", Description: "one time only"}, + "QUADWEEKLY": {Key: "QUADWEEKLY", Value: 1095, String: "quad-weekly", Description: "every four weeks"}, + "QUARTERLY": {Key: "QUARTERLY", Value: 336, String: "quarterly", Description: "four times per year"}, + "SEMIANNUALLY": {Key: "SEMIANNUALLY", Value: 168, String: "semi-annually", Description: "twice per year"}, + "SEMIMONTHLY": {Key: "SEMIMONTHLY", Value: 2016, String: "semi-monthly", Description: "twice per month"}, + "TREANNUALLY": {Key: "TREANNUALLY", Value: 28, String: "tre-annually", Description: "every three years"}, + "TREQUADWEEKLY": {Key: "TREQUADWEEKLY", Value: 365, String: "tre-quad-weekly", Description: "every twelve weeks"}, + "TRIANNUALLY": {Key: "TRIANNUALLY", Value: 252, String: "tri-annually", Description: "three times per year"}, + "WEEKLY": {Key: "WEEKLY", Value: 4380, String: "weekly", Description: "once per week"}, + } +) diff --git a/cadence_test.go b/cadence_test.go new file mode 100644 index 0000000..83938a6 --- /dev/null +++ b/cadence_test.go @@ -0,0 +1,159 @@ +package cadence + +import ( + "errors" + "fmt" + "math" + "testing" + "time" + + "github.com/cucumber/godog" +) + +type testData struct { + cad1, cad2 CadenceObj + str1, str2 string + float1, float2 float64 + testDate time.Time + nextDate time.Time +} + +func TestCucumberFeatures(t *testing.T) { + suite := godog.TestSuite{ + ScenarioInitializer: InitializeScenario, + Options: &godog.Options{ + Format: "pretty", + Paths: []string{"features"}, + TestingT: t, + }, + } + + if suite.Run() != 0 { + t.Fatal("non-zero status returned, failed to run cucumber tests") + } +} + +// Given Callbacks +func (td *testData) aNewCadenceObject(key string) (err error) { + td.cad1, err = Cadence.New(key) + + return +} + +func (td *testData) aSecondCadenceObject(key string) (err error) { + td.cad2, err = Cadence.New(key) + + return +} + +func (td *testData) theDateIs(year, month, day int) (err error) { + td.testDate = time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) + + return +} + +// When Callbacks +func (td *testData) iCallTheVersionMethod() (err error) { + td.str1 = Cadence.Version + + return +} + +func (td *testData) howManyTimesIn() (err error) { + td.float1, err = td.cad1.TimesIn(td.cad2) + + return +} + +func (td *testData) whenICallNext() (err error) { + td.nextDate, err = td.cad1.Next(td.testDate) + + return +} + +func (td *testData) whenICallNext3() (err error) { + td.nextDate, err = td.cad1.NextN(td.testDate, 3) + + return +} + +// Then Callbacks +func (td *testData) itWillReturn(versionStr string) (err error) { + if td.str1 != versionStr { + errText := fmt.Sprintf("ERROR: goCadence: Invalid Version: got: %s, exp:%s", td.str1, versionStr) + err = errors.New(errText) + } + + return +} + +func (td *testData) verifyDescription(expected string) (err error) { + if td.cad1.Description != expected { + errText := fmt.Sprintf("ERROR: goCadence: Invalid Description: got: %s, exp:%s", td.cad1.Description, expected) + err = errors.New(errText) + } + + return +} + +func (td *testData) verifyString(expected string) (err error) { + if td.cad1.String != expected { + errText := fmt.Sprintf("ERROR: goCadence: Invalid String: got: %s, exp:%s", td.cad1.String, expected) + err = errors.New(errText) + } + + return +} + +func (td *testData) verifyValue(expected int64) (err error) { + if td.cad1.Value != expected { + errText := fmt.Sprintf("ERROR: goCadence: Invalid Value: got: %d, exp:%d", td.cad1.Value, expected) + err = errors.New(errText) + } + + return +} + +func (td *testData) testFloatValue(expected float64) (err error) { + diff := math.Abs(td.float1 - expected) + if diff > 0.000001 { + errText := fmt.Sprintf("ERROR: goCadence: Invalid Value: got: %f, exp:%f", td.float1, expected) + err = errors.New(errText) + } + + return +} + +func (td *testData) verifyDate(year, month, day int) (err error) { + expected := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) + if td.nextDate != expected { + dateFormat := time.RFC822 + errText := fmt.Sprintf("ERROR: goCadence: Invalid Value: got: %s, exp:%s", td.nextDate.Format(dateFormat), expected.Format(dateFormat)) + err = errors.New(errText) + } + + return +} + +func InitializeScenario(sc *godog.ScenarioContext) { + td := testData{} + + // Given Mappings + sc.Step(`^a new (.*) cadence object$`, td.aNewCadenceObject) + sc.Step(`^a second cadence of (.*)$`, td.aSecondCadenceObject) + sc.Step(`^the date is (\d+)-(\d+)-(\d+)$`, td.theDateIs) + + // When Mappings + sc.Step(`^I call the version method$`, td.iCallTheVersionMethod) + sc.Step(`^I ask how many times it is in this second cadence$`, td.howManyTimesIn) + sc.Step(`^I call the next function with the test date$`, td.whenICallNext) + sc.Step(`^I request the third occurance from the test date$`, td.whenICallNext3) + + // Then Mappings + sc.Step(`^it will return "([^"]*)"$`, td.itWillReturn) + sc.Step(`^its description should be "([^"]*)"$`, td.verifyDescription) + sc.Step(`^its string value should be "([^"]*)"$`, td.verifyString) + sc.Step(`^its value whould be (\d+)$`, td.verifyValue) + sc.Step(`^I should get a floating point value of (\d+\.\d+)$`, td.testFloatValue) + sc.Step(`^i should get a date of (\d+)-(\d+)-(\d+)$`, td.verifyDate) +} diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..358758d --- /dev/null +++ b/changelog.md @@ -0,0 +1,25 @@ +# Changelog + +## Pre-Release + +### 0.0.1 +*28 Sept 2022* + + * Setup Repo + * Setup Cucumber Testing + * Got Cucumber tests running from Go Test + * Built 1st test to return a version string + +### 0.0.2 +*29 Sept 2022* + + * Added initial set of Cadence definitions + * exposed string equivalents for cadence names + * exposed descriptions for cadences + * added methods to calculate the number of times a cadence occurs inside another cadence + +### 0.0.3 +*29 Sept 2022* + + * Added date functions (ie. given a date, and a cadence, when will the next occurrence happen) + * Find date of the N-th occurrence of cadence \ No newline at end of file diff --git a/features/admin.feature b/features/admin.feature new file mode 100644 index 0000000..6343372 --- /dev/null +++ b/features/admin.feature @@ -0,0 +1,8 @@ +Feature: Administrative Tests + In order allow developers to adjust to changing features + As a developer + I need to be able to get metadata about the library + + Scenario: Check lib Version + When I call the version method + Then it will return "0.0.3" diff --git a/features/annually.feature b/features/annually.feature new file mode 100644 index 0000000..048bb30 --- /dev/null +++ b/features/annually.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a annually basis + As a developer + I want to create an instance of Cadence that can handle annually occurances + + Background: + Given a new ANNUALLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 84 + + Scenario: Verity its string value + Then its string value should be "annually" + + Scenario: Veryify is description value + Then its description should be "once per year" + + Scenario: How many times does ANNUALLY occur in TREANNUALLY + Given a second cadence of TREANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 3.0 + + Scenario: How many times does ANNUALLY occur in SEMIANNUALLY + Given a second cadence of SEMIANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 0.500000 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2023-04-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2025-04-04 diff --git a/features/biannually.feature b/features/biannually.feature new file mode 100644 index 0000000..50439ef --- /dev/null +++ b/features/biannually.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a bi-annually basis + As a developer + I want to create an instance of Cadence that can handle bi-annually occurances + + Background: + Given a new BIANNUALLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 42 + + Scenario: Verity its string value + Then its string value should be "bi-annually" + + Scenario: Veryify is description value + Then its description should be "every two years" + + Scenario: How many times does BIANNUALLY occur in BIANNUALLY + Given a second cadence of BIANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.0 + + Scenario: How many times does BIANNUALLY occur in TREANNUALLY + Given a second cadence of TREANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.500000 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2024-04-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2028-04-04 diff --git a/features/bimonthly.feature b/features/bimonthly.feature new file mode 100644 index 0000000..08f7436 --- /dev/null +++ b/features/bimonthly.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a bi-monthly basis + As a developer + I want to create an instance of Cadence that can handle bi-monthly occurances + + Background: + Given a new BIMONTHLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 504 + + Scenario: Verity its string value + Then its string value should be "bi-monthly" + + Scenario: Veryify is description value + Then its description should be "every two months" + + Scenario: How many times does BIMONTHLY occur in TRIANNUALLY + Given a second cadence of TRIANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 2.0 + + Scenario: How many times does BIMONTHLY occur in TREQUADWEEKLY + Given a second cadence of TREQUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.380822 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-06-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-10-04 diff --git a/features/biweekly.feature b/features/biweekly.feature new file mode 100644 index 0000000..c08ad23 --- /dev/null +++ b/features/biweekly.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a bi-weekly basis + As a developer + I want to create an instance of Cadence that can handle bi-weekly occurances + + Background: + Given a new BIWEEKLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 2190 + + Scenario: Verity its string value + Then its string value should be "bi-weekly" + + Scenario: Veryify is description value + Then its description should be "every two weeks" + + Scenario: How many times does BIWEEKLY occur in TREQUADWEEKLY + Given a second cadence of TREQUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 6.0 + + Scenario: How many times does BIWEEKLY occur in ANNUALLY + Given a second cadence of ANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 26.071429 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-04-18 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-05-16 diff --git a/features/daily.feature b/features/daily.feature new file mode 100644 index 0000000..f25b887 --- /dev/null +++ b/features/daily.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a daily basis + As a developer + I want to create an instance of Cadence that can handle daily occurances + + Background: + Given a new DAILY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 30660 + + Scenario: Verity its string value + Then its string value should be "daily" + + Scenario: Veryify is description value + Then its description should be "every day" + + Scenario: How many times does DAILY occur in WEEKLY + Given a second cadence of WEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 7.0 + + Scenario: How many times does DAILY occur in MONTHLY + Given a second cadence of MONTHLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 30.416666 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-04-05 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-04-07 diff --git a/features/monthly.feature b/features/monthly.feature new file mode 100644 index 0000000..ffa9d2d --- /dev/null +++ b/features/monthly.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a monthly basis + As a developer + I want to create an instance of Cadence that can handle monthly occurances + + Background: + Given a new MONTHLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 1008 + + Scenario: Verity its string value + Then its string value should be "monthly" + + Scenario: Veryify is description value + Then its description should be "once per month" + + Scenario: How many times does MONTHLY occur in ANNUALLY + Given a second cadence of ANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 12.0 + + Scenario: How many times does MONTHLY occur in TREQUADWEEKLY + Given a second cadence of TREQUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 2.761644 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-05-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-07-04 diff --git a/features/once.feature b/features/once.feature new file mode 100644 index 0000000..ff7edbc --- /dev/null +++ b/features/once.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a once basis + As a developer + I want to create an instance of Cadence that can handle once occurances + + Background: + Given a new ONCE cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 0 + + Scenario: Verity its string value + Then its string value should be "once" + + Scenario: Veryify is description value + Then its description should be "one time only" + + Scenario: How many times does ONCE occur in TREQUADWEEKLY + Given a second cadence of TREQUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.0 + + Scenario: How many times does ONCE occur in MONTHLY + Given a second cadence of MONTHLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.0 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-04-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-04-04 diff --git a/features/quadweekly.feature b/features/quadweekly.feature new file mode 100644 index 0000000..22d0ed7 --- /dev/null +++ b/features/quadweekly.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a quad-weekly basis + As a developer + I want to create an instance of Cadence that can handle quad-weekly occurances + + Background: + Given a new QUADWEEKLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 1095 + + Scenario: Verity its string value + Then its string value should be "quad-weekly" + + Scenario: Veryify is description value + Then its description should be "every four weeks" + + Scenario: How many times does QUADWEEKLY occur in TREQUADWEEKLY + Given a second cadence of TREQUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 3.0 + + Scenario: How many times does QUADWEEKLY occur in MONTHLY + Given a second cadence of MONTHLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.086310 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-05-02 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-06-27 diff --git a/features/quarterly.feature b/features/quarterly.feature new file mode 100644 index 0000000..6969c5e --- /dev/null +++ b/features/quarterly.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a quarterly basis + As a developer + I want to create an instance of Cadence that can handle quarterly occurances + + Background: + Given a new QUARTERLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 336 + + Scenario: Verity its string value + Then its string value should be "quarterly" + + Scenario: Veryify is description value + Then its description should be "four times per year" + + Scenario: How many times does QUARTERLY occur in ANNUALLY + Given a second cadence of ANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 4.0 + + Scenario: How many times does QUARTERLY occur in TRiANNUALLY + Given a second cadence of TRiANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.333333 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-07-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2023-01-04 diff --git a/features/semiannually.feature b/features/semiannually.feature new file mode 100644 index 0000000..1642ade --- /dev/null +++ b/features/semiannually.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a semi-annually basis + As a developer + I want to create an instance of Cadence that can handle semi-annually occurances + + Background: + Given a new SEMIANNUALLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 168 + + Scenario: Verity its string value + Then its string value should be "semi-annually" + + Scenario: Veryify is description value + Then its description should be "twice per year" + + Scenario: How many times does SEMIANNUALLY occur in BIANNUALLY + Given a second cadence of BIANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 4.0 + + Scenario: How many times does SEMIANNUALLY occur in TRIANNUALLY + Given a second cadence of TRIANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 0.666667 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-10-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2023-10-04 diff --git a/features/semimonthly.feature b/features/semimonthly.feature new file mode 100644 index 0000000..6dfc10b --- /dev/null +++ b/features/semimonthly.feature @@ -0,0 +1,41 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a semi-monthly basis + As a developer + I want to create an instance of Cadence that can handle semi-monthly occurances + + Background: + Given a new SEMIMONTHLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 2016 + + Scenario: Verity its string value + Then its string value should be "semi-monthly" + + Scenario: Veryify is description value + Then its description should be "twice per month" + + Scenario: How many times does SEMIMONTHLY occur in QUARTERLY + Given a second cadence of QUARTERLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 6.0 + + Scenario: How many times does SEMIMONTHLY occur in TREQUADWEEKLY + Given a second cadence of TREQUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 5.523288 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-04-15 + + Scenario: What is the next date given our test date? + Given the date is 2022-04-20 + When I call the next function with the test date + Then i should get a date of 2022-04-30 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-05-15 diff --git a/features/treannually.feature b/features/treannually.feature new file mode 100644 index 0000000..6cd86b4 --- /dev/null +++ b/features/treannually.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a tre-annually basis + As a developer + I want to create an instance of Cadence that can handle tre-annually occurances + + Background: + Given a new TREANNUALLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 28 + + Scenario: Verity its string value + Then its string value should be "tre-annually" + + Scenario: Veryify is description value + Then its description should be "every three years" + + Scenario: How many times does TREANNUALLY occur in TREANNUALLY + Given a second cadence of TREANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.0 + + Scenario: How many times does TREANNUALLY occur in BIANNUALLY + Given a second cadence of BIANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 0.666666 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2025-04-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2031-04-04 diff --git a/features/trequadweekly.feature b/features/trequadweekly.feature new file mode 100644 index 0000000..f1aa43b --- /dev/null +++ b/features/trequadweekly.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a tre-quad-weekly basis + As a developer + I want to create an instance of Cadence that can handle tre-quad-weekly occurances + + Background: + Given a new TREQUADWEEKLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 365 + + Scenario: Verity its string value + Then its string value should be "tre-quad-weekly" + + Scenario: Veryify is description value + Then its description should be "every twelve weeks" + + Scenario: How many times does TREQUADWEEKLY occur in TREQUADWEEKLY + Given a second cadence of TREQUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.0 + + Scenario: How many times does TREQUADWEEKLY occur in QUADWEEKLY + Given a second cadence of QUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 0.333333 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-06-27 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-12-12 diff --git a/features/triannually.feature b/features/triannually.feature new file mode 100644 index 0000000..c4af75c --- /dev/null +++ b/features/triannually.feature @@ -0,0 +1,36 @@ +Feature: Daily Cadence Object + + In order to handle items that occur on a tri-annually basis + As a developer + I want to create an instance of Cadence that can handle tri-annually occurances + + Background: + Given a new TRIANNUALLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 252 + + Scenario: Verity its string value + Then its string value should be "tri-annually" + + Scenario: Veryify is description value + Then its description should be "three times per year" + + Scenario: How many times does TRIANNUALLY occur in TREANNUALLY + Given a second cadence of TREANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 9.0 + + Scenario: How many times does TRIANNUALLY occur in SEMIANNUALLY + Given a second cadence of SEMIANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 1.500000 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-08-04 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2023-04-04 diff --git a/features/weekly.feature b/features/weekly.feature new file mode 100644 index 0000000..a98c783 --- /dev/null +++ b/features/weekly.feature @@ -0,0 +1,36 @@ +Feature: Weekly Cadence Object + + In order to handle items that occur on a weekly basis + As a developer + I want to create an instance of Cadence that can handle events that occur once per week + + Background: + Given a new WEEKLY cadence object + And the date is 2022-04-04 + + Scenario: Verify its weighting value + Then its value whould be 4380 + + Scenario: Verity its string value + Then its string value should be "weekly" + + Scenario: Veryify is description value + Then its description should be "once per week" + + Scenario: How many times does WEEKLY occur in TREQUADWEEKLY + Given a second cadence of TREQUADWEEKLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 12.0 + + Scenario: How many times does WEEKLY occur in ANNUALLY + Given a second cadence of ANNUALLY + When I ask how many times it is in this second cadence + Then I should get a floating point value of 52.142857 + + Scenario: What is the next date given our test date? + When I call the next function with the test date + Then i should get a date of 2022-04-11 + + Scenario: What is the 3rd date given our test date? + When I request the third occurance from the test date + Then i should get a date of 2022-04-25 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..db6fc5f --- /dev/null +++ b/go.mod @@ -0,0 +1,15 @@ +module cadence + +go 1.22.4 + +require github.com/cucumber/godog v0.14.1 + +require ( + github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect + github.com/cucumber/messages/go/v21 v21.0.1 // indirect + github.com/gofrs/uuid v4.3.1+incompatible // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-memdb v1.3.4 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/spf13/pflag v1.0.5 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..fc881b8 --- /dev/null +++ b/go.sum @@ -0,0 +1,48 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= +github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= +github.com/cucumber/godog v0.14.1 h1:HGZhcOyyfaKclHjJ+r/q93iaTJZLKYW6Tv3HkmUE6+M= +github.com/cucumber/godog v0.14.1/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces= +github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= +github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= +github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= +github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= +github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=