Agents naturally use spawn-style (variable=value) for both spawn and distill commands. Now distill accepts both: - --var branch=feature-auth (spawn-style) - --var feature-auth=branch (substitution-style) Smart detection checks which side appears in the epic text: - Right side found → spawn-style (left is varname) - Left side found → substitution-style (left is value) - Both found → prefers spawn-style (more common guess) Embodies the Beads philosophy: watch what agents do, make their guess correct. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
160 lines
3.7 KiB
Go
160 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/steveyegge/beads/internal/types"
|
|
)
|
|
|
|
func TestParseDistillVar(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
varFlag string
|
|
searchableText string
|
|
wantFind string
|
|
wantVar string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "spawn-style: variable=value",
|
|
varFlag: "branch=feature-auth",
|
|
searchableText: "Implement feature-auth login flow",
|
|
wantFind: "feature-auth",
|
|
wantVar: "branch",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "substitution-style: value=variable",
|
|
varFlag: "feature-auth=branch",
|
|
searchableText: "Implement feature-auth login flow",
|
|
wantFind: "feature-auth",
|
|
wantVar: "branch",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "spawn-style with version number",
|
|
varFlag: "version=1.2.3",
|
|
searchableText: "Release version 1.2.3 to production",
|
|
wantFind: "1.2.3",
|
|
wantVar: "version",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "both found - prefers spawn-style",
|
|
varFlag: "api=api",
|
|
searchableText: "The api endpoint uses api keys",
|
|
wantFind: "api",
|
|
wantVar: "api",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "neither found - error",
|
|
varFlag: "foo=bar",
|
|
searchableText: "Nothing matches here",
|
|
wantFind: "",
|
|
wantVar: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "empty left side - error",
|
|
varFlag: "=value",
|
|
searchableText: "Some text with value",
|
|
wantFind: "",
|
|
wantVar: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "empty right side - error",
|
|
varFlag: "value=",
|
|
searchableText: "Some text with value",
|
|
wantFind: "",
|
|
wantVar: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "no equals sign - error",
|
|
varFlag: "noequals",
|
|
searchableText: "Some text",
|
|
wantFind: "",
|
|
wantVar: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "value with equals sign",
|
|
varFlag: "env=KEY=VALUE",
|
|
searchableText: "Set KEY=VALUE in config",
|
|
wantFind: "KEY=VALUE",
|
|
wantVar: "env",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "partial match in longer word - finds it",
|
|
varFlag: "name=auth",
|
|
searchableText: "authentication module",
|
|
wantFind: "auth",
|
|
wantVar: "name",
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gotFind, gotVar, err := parseDistillVar(tt.varFlag, tt.searchableText)
|
|
|
|
if tt.wantErr {
|
|
if err == nil {
|
|
t.Errorf("parseDistillVar() expected error, got none")
|
|
}
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
t.Errorf("parseDistillVar() unexpected error: %v", err)
|
|
return
|
|
}
|
|
|
|
if gotFind != tt.wantFind {
|
|
t.Errorf("parseDistillVar() find = %q, want %q", gotFind, tt.wantFind)
|
|
}
|
|
if gotVar != tt.wantVar {
|
|
t.Errorf("parseDistillVar() var = %q, want %q", gotVar, tt.wantVar)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCollectSubgraphText(t *testing.T) {
|
|
// Create a simple subgraph for testing
|
|
subgraph := &MoleculeSubgraph{
|
|
Issues: []*types.Issue{
|
|
{
|
|
Title: "Epic: Feature Auth",
|
|
Description: "Implement authentication",
|
|
Design: "Use OAuth2",
|
|
},
|
|
{
|
|
Title: "Add login endpoint",
|
|
Notes: "See RFC 6749",
|
|
},
|
|
},
|
|
}
|
|
|
|
text := collectSubgraphText(subgraph)
|
|
|
|
// Verify all fields are included
|
|
expected := []string{
|
|
"Epic: Feature Auth",
|
|
"Implement authentication",
|
|
"Use OAuth2",
|
|
"Add login endpoint",
|
|
"See RFC 6749",
|
|
}
|
|
|
|
for _, exp := range expected {
|
|
if !strings.Contains(text, exp) {
|
|
t.Errorf("collectSubgraphText() missing %q", exp)
|
|
}
|
|
}
|
|
}
|