85 lines
4.1 KiB
Go
85 lines
4.1 KiB
Go
package walking_skeleton_test
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"git.cin.su/m/Assistant/contracts/authority"
|
|
"git.cin.su/m/Assistant/contracts/identity"
|
|
situationcontract "git.cin.su/m/Assistant/contracts/situation"
|
|
workcontract "git.cin.su/m/Assistant/contracts/work"
|
|
situation "git.cin.su/m/Assistant/modules/situation/domain"
|
|
work "git.cin.su/m/Assistant/modules/work/domain"
|
|
"git.cin.su/m/Assistant/platform/ids"
|
|
)
|
|
|
|
func TestWS001FocusIsolationPreventsWrongProjectMutation(t *testing.T) {
|
|
actor := identity.ActorID(ids.ID("actor"))
|
|
scope := authority.ScopeID(ids.ID("scope"))
|
|
project := situationcontract.ProjectID(ids.ID("same-repository"))
|
|
goalA := workcontract.GoalID(ids.ID("goal-a"))
|
|
goalB := workcontract.GoalID(ids.ID("goal-b"))
|
|
bindings := []situationcontract.FocusBinding{
|
|
{ID: situationcontract.FocusBindingID(ids.ID("focus-a")), ActorID: actor, SessionID: situationcontract.SessionID(ids.ID("session-a")), Workspace: situationcontract.WorkspaceID(ids.ID("worktree-a")), ProjectID: project, GoalID: goalA, ScopeID: scope, Active: true},
|
|
{ID: situationcontract.FocusBindingID(ids.ID("focus-b")), ActorID: actor, SessionID: situationcontract.SessionID(ids.ID("session-b")), Workspace: situationcontract.WorkspaceID(ids.ID("worktree-b")), ProjectID: project, GoalID: goalB, ScopeID: scope, Active: true},
|
|
}
|
|
resolver := situation.NewResolver(bindings)
|
|
store := work.NewStore([]work.Task{
|
|
{ID: workcontract.TaskID(ids.ID("task-a")), GoalID: goalA, ScopeID: scope, Revision: 1},
|
|
{ID: workcontract.TaskID(ids.ID("task-b")), GoalID: goalB, ScopeID: scope, Revision: 1},
|
|
})
|
|
|
|
// The identical phrase is intentionally not supplied to resolution: runtime
|
|
// session/workspace bindings, including two worktrees of one repository,
|
|
// are the only project-selection inputs.
|
|
focusA, err := resolver.Resolve(situationcontract.RuntimeBinding{SessionID: bindings[0].SessionID, Workspace: bindings[0].Workspace})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
focusB, err := resolver.Resolve(situationcontract.RuntimeBinding{SessionID: bindings[1].SessionID, Workspace: bindings[1].Workspace})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if focusA.GoalID == focusB.GoalID {
|
|
t.Fatal("two worktrees resolved to the same goal")
|
|
}
|
|
|
|
wrongTarget := workcontract.TaskTarget{TaskID: workcontract.TaskID(ids.ID("task-b")), GoalID: goalB, ScopeID: scope, Revision: 1}
|
|
if err := situation.ValidateTaskTarget(focusA, wrongTarget); !errors.Is(err, situation.ErrTargetMismatch) {
|
|
t.Fatalf("wrong cognition target error = %v, want ErrTargetMismatch", err)
|
|
}
|
|
|
|
targetA := workcontract.TaskTarget{TaskID: workcontract.TaskID(ids.ID("task-a")), GoalID: goalA, ScopeID: scope, Revision: 1}
|
|
if err := situation.ValidateTaskTarget(focusA, targetA); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
committed, err := store.Commit(targetA)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if committed.Revision != 2 {
|
|
t.Fatalf("revision = %d, want 2", committed.Revision)
|
|
}
|
|
if _, err := store.Commit(targetA); !errors.Is(err, work.ErrRevisionConflict) {
|
|
t.Fatalf("stale revision error = %v, want ErrRevisionConflict", err)
|
|
}
|
|
if _, err := store.Commit(wrongTarget); err != nil {
|
|
t.Fatalf("other context must retain its original revision: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestWS001RejectsStaleAndAmbiguousFocusWithoutMutation(t *testing.T) {
|
|
runtime := situationcontract.RuntimeBinding{SessionID: situationcontract.SessionID(ids.ID("session")), Workspace: situationcontract.WorkspaceID(ids.ID("workspace"))}
|
|
stale := situation.NewResolver([]situationcontract.FocusBinding{{SessionID: runtime.SessionID, Workspace: runtime.Workspace, Active: false}})
|
|
if _, err := stale.Resolve(runtime); !errors.Is(err, situation.ErrStaleFocus) {
|
|
t.Fatalf("stale error = %v, want ErrStaleFocus", err)
|
|
}
|
|
ambiguous := situation.NewResolver([]situationcontract.FocusBinding{
|
|
{ID: situationcontract.FocusBindingID(ids.ID("one")), SessionID: runtime.SessionID, Workspace: runtime.Workspace, Active: true},
|
|
{ID: situationcontract.FocusBindingID(ids.ID("two")), SessionID: runtime.SessionID, Workspace: runtime.Workspace, Active: true},
|
|
})
|
|
if _, err := ambiguous.Resolve(runtime); !errors.Is(err, situation.ErrAmbiguousFocus) {
|
|
t.Fatalf("ambiguity error = %v, want ErrAmbiguousFocus", err)
|
|
}
|
|
}
|