2afa4c6ee0
- Add parseRelativeExpression() to detect pattern: attr+/-duration - Add resolveDateValue() to resolve absolute or relative dates - Add applyDateAttribute() helper for date attributes with relative support - Track attribute order in Modifier struct (AttributeOrder field) - Refactor Apply() and ApplyToNew() to process attrs in order - Support chaining: due:mon scheduled:due-3d wait:scheduled-1d - Support addition and subtraction: due+1y, wait-2d - Add comprehensive test suite for relative expressions - Error if referencing undefined date attribute - All 38+ tests passing
135 lines
3.1 KiB
Go
135 lines
3.1 KiB
Go
package engine
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestRelativeDateExpressions(t *testing.T) {
|
|
task, err := CreateTask("Test task with relative dates")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
mods := []string{"due:mon", "wait:due-1d"}
|
|
modifier, err := ParseModifier(mods)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = modifier.Apply(task)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if task.Due == nil || task.Wait == nil {
|
|
t.Fatal("Due and wait should be set")
|
|
}
|
|
|
|
expectedWait := task.Due.AddDate(0, 0, -1)
|
|
if !task.Wait.Equal(expectedWait) {
|
|
t.Errorf("Wait should be 1 day before due. Expected %v, got %v", expectedWait, *task.Wait)
|
|
}
|
|
}
|
|
|
|
func TestRelativeDateChaining(t *testing.T) {
|
|
task, err := CreateTask("Test chained relative dates")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
mods := []string{"due:mon", "scheduled:due-3d", "wait:scheduled-1d"}
|
|
modifier, err := ParseModifier(mods)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = modifier.Apply(task)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if task.Due == nil || task.Scheduled == nil || task.Wait == nil {
|
|
t.Fatal("All dates should be set")
|
|
}
|
|
|
|
expectedScheduled := task.Due.AddDate(0, 0, -3)
|
|
if !task.Scheduled.Equal(expectedScheduled) {
|
|
t.Errorf("Scheduled should be 3 days before due. Expected %v, got %v", expectedScheduled, *task.Scheduled)
|
|
}
|
|
|
|
expectedWait := task.Scheduled.AddDate(0, 0, -1)
|
|
if !task.Wait.Equal(expectedWait) {
|
|
t.Errorf("Wait should be 1 day before scheduled. Expected %v, got %v", expectedWait, *task.Wait)
|
|
}
|
|
}
|
|
|
|
func TestRelativeDateAddition(t *testing.T) {
|
|
task, err := CreateTask("Test relative date addition")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
mods := []string{"due:today", "until:due+1y"}
|
|
modifier, err := ParseModifier(mods)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = modifier.Apply(task)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if task.Due == nil || task.Until == nil {
|
|
t.Fatal("Due and until should be set")
|
|
}
|
|
|
|
expectedUntil := task.Due.AddDate(1, 0, 0)
|
|
diff := task.Until.Sub(expectedUntil)
|
|
if diff < -24*time.Hour || diff > 24*time.Hour {
|
|
t.Errorf("Until should be ~1 year after due. Expected %v, got %v (diff: %v)", expectedUntil, *task.Until, diff)
|
|
}
|
|
}
|
|
|
|
func TestRelativeDateReferenceError(t *testing.T) {
|
|
task, err := CreateTask("Test reference error")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
mods := []string{"wait:due-1d"}
|
|
modifier, err := ParseModifier(mods)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = modifier.Apply(task)
|
|
if err == nil {
|
|
t.Error("Should error when referencing unset date")
|
|
}
|
|
}
|
|
|
|
func TestRelativeDateInNewTask(t *testing.T) {
|
|
// Test relative dates when creating a new task via CreateTaskWithModifier
|
|
mods := []string{"due:tomorrow", "wait:due-2d"}
|
|
modifier, err := ParseModifier(mods)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
task, err := CreateTaskWithModifier("New task with relative dates", modifier)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if task.Due == nil || task.Wait == nil {
|
|
t.Fatal("Due and wait should be set")
|
|
}
|
|
|
|
expectedWait := task.Due.AddDate(0, 0, -2)
|
|
if !task.Wait.Equal(expectedWait) {
|
|
t.Errorf("Wait should be 2 days before due. Expected %v, got %v", expectedWait, *task.Wait)
|
|
}
|
|
}
|